摘要:引擎會在代碼執(zhí)行前進行詞法分析,所以事實上,運行分為此法分析和執(zhí)行兩個階段。詞法作用域所謂詞法作用域是說,其作用域為在定義時詞法分析時就確定下來的,而并非在執(zhí)行時確定。
先來看個常見的面試題如下:
var a = 10; function test(){ alert(a); //undefined var a = 20; alert(a); //20 } test();
疑問:為什么呢?test()執(zhí)行時,雖然a=20沒有賦值,但是父級作用域里是有a=10的,不應該是undefined呀,js是按順序執(zhí)行的,此時的var num = 20;根本沒有執(zhí)行,所以應該是10??!你是不是也是這么認為的,就和我當初一樣???
分析:眾所周知,js代碼是自上而下執(zhí)行的,JavaScript并不是傳統(tǒng)的塊級作用域,而是函數(shù)作用域。JavaScript引擎會在代碼執(zhí)行前進行詞法分析,所以事實上,js運行分為此法分析和執(zhí)行兩個階段。
JavaScript代碼運行前有一個類似編譯的過程即詞法分析,詞法分析主要有三個步驟:
分析參數(shù)
再分析變量的聲明
分析函數(shù)聲明
具體步驟如下:
函數(shù)在運行的瞬間,生成一個活動對象(Active Object),簡稱AO
第一步:分析參數(shù):
函數(shù)接收形式參數(shù),添加到AO的屬性,并且這個時候值為undefined,即AO.name=undefined
接收實參,添加到AO的屬性,覆蓋之前的undefined
第二步:分析變量聲明:如var name;或var name="mary";
如果上一步分析參數(shù)中AO還沒有name屬性,則添加AO屬性為undefined,即AO.name=undefined
如果AO上面已經(jīng)有name屬性了,則不作任何修改
第三步:分析函數(shù)的聲明:
如果有function name(){}把函數(shù)賦給AO.name ,覆蓋上一步分析的值
分析下面這個栗子:
1.var a = 10; 2.function test(a){ 3. alert(a); //function a (){} 4. var a = 20; 5. alert(a); //20 6. function a (){} 7. alert(a); //20 8. } 9. 10.test(100);
詞法分析:
第一步,分析函數(shù)參數(shù):
形式參數(shù):AO.a = undefined 接收實參:AO.a = 100
第二步,分析局部變量:
第4行代碼有var a,但是此時已有AO.a = 100,所以不做任何修改,即AO.a = 100
第三步,分析函數(shù)聲明:
第6行代碼有函數(shù)a,則將function a(){}賦給AO.a,即AO.a = function a(){}
執(zhí)行代碼時:
第3行代碼運行時拿到的a時詞法分析后的AO.a,即AO.a = function a(){}; 第4行代碼:將20賦值給a,此時a=20; 第5行代碼運行時a已經(jīng)被賦值為20,結果20; 第6行代碼是一個函數(shù)表達式,所以不做任何操作; 第7行代碼運行時仍是20;
ps:
1.var a = 10; 2.function test(a){ 3. var a; //證明詞法分析第二步。 4. alert(a); //100 5. a = 20; 6. alert(a); //20 7.} 7.test(100);
ps:
var a = 10; function test(a){ alert(a); //100 var a = 20; alert(a); //20 a = function(){} //是賦值,只有在執(zhí)行時才有效 alert(a); //function(){} } test(100);
ps:(執(zhí)行結果同上)
var a = 10; function test(a){ alert(a); //100 var a = 20; alert(a); //20 var a = function(){} //是賦值,只有在執(zhí)行時才有效 alert(a); //function(){} } test(100);
補充說明:函數(shù)聲明與函數(shù)表達式
//函數(shù)聲明 function a(){ } //函數(shù)表達式 var b = function(){ }
a和b在詞法分析時,區(qū)別:
a在詞法分析時,就發(fā)揮作用; b只有在執(zhí)行階段,才發(fā)揮作用。
詞法作用域
所謂詞法作用域是說,其作用域為在定義時(詞法分析時)就確定下來的,而并非在執(zhí)行時確定。白話就是在函數(shù)未執(zhí)行前,函數(shù)執(zhí)行的順序已經(jīng)被確定,而不是類似JAVA一樣,是在執(zhí)行前根本不知道執(zhí)行順序。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83976.html
摘要:引擎會在代碼執(zhí)行前進行詞法分析,所以事實上,運行分為此法分析和執(zhí)行兩個階段。詞法作用域所謂詞法作用域是說,其作用域為在定義時詞法分析時就確定下來的,而并非在執(zhí)行時確定。 先來看個常見的面試題如下: var a = 10; function test(){ alert(a); //undefined var a = 20; alert(a); //20 } te...
摘要:下面我們就羅列閉包的幾個常見問題,從回答問題的角度來理解和定義你們心中的閉包。函數(shù)可以通過作用域鏈相互關聯(lián)起來,函數(shù)內(nèi)部的變量可以保存在其他函數(shù)作用域內(nèi),這種特性在計算機科學文獻中稱為閉包。 寫這篇文章之前,我對閉包的概念及原理模糊不清,一直以來都是以通俗的外層函數(shù)包裹內(nèi)層....來欺騙自己。并沒有說這種說法的對與錯,我只是不想擁有從眾心理或者也可以說如果我們說出更好更低層的東西,逼格...
摘要:原文原文原文詞法作用域作用域有兩種常見的模型,一種叫做詞法作用域,一種叫做動態(tài)作用域。其中詞法作用域更常見,被大多數(shù)語言采用,包括。值得注意的是,一個函數(shù)作用域只有可能存在于一個父級作用域中,不會同時存在兩個父級作用域。 原文: 原文1 | 原文2 Lexical Scope - 詞法作用域 作用域有兩種常見的模型,一種叫做 詞法作用域 Lexical Scope,一種叫做...
摘要:詞法作用域定義在詞法階段的作用域由你在寫代碼時將變量和塊作用域?qū)懺谀膩頉Q定的,因此當詞法分析器處理代碼時會保持作用域不變。欺騙詞法作用域在詞法分析器處理過后依然可以修改作用域。 你不知道的JS(上卷)筆記 你不知道的 JavaScript JavaScript 既是一門充滿吸引力、簡單易用的語言,又是一門具有許多復雜微妙技術的語言,即使是經(jīng)驗豐富的 JavaScript 開發(fā)者,如果沒...
閱讀 2788·2021-11-17 09:33
閱讀 3131·2021-10-25 09:44
閱讀 1233·2021-10-11 10:59
閱讀 2437·2021-09-27 13:34
閱讀 2933·2021-09-07 10:19
閱讀 2171·2019-08-29 18:46
閱讀 1558·2019-08-29 12:55
閱讀 955·2019-08-23 17:11