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