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