你不懂JS:作用域與閉包 附錄A:動(dòng)態(tài)作用域

官方中文版原文鏈接

感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大獎(jiǎng):點(diǎn)擊這里領(lǐng)取

在第二章中,作為與JavaScript中(事實(shí)上,其他大多數(shù)語言也是)作用域的工作方式模型 —— “詞法作用域”的對(duì)比,我們談到了“動(dòng)態(tài)作用域”。

我們將簡(jiǎn)單地檢視動(dòng)態(tài)作用域,來徹底說明這種比較。但更重要的是,對(duì)于JavaScript中的另一種機(jī)制(this)來說動(dòng)態(tài)作用域?qū)嶋H上是它的一個(gè)近親表兄,我們將在本系列的“this與對(duì)象原型”中詳細(xì)講解這種機(jī)制。

正如我們?cè)诘诙轮锌吹降模~法作用域是一組關(guān)于 引擎 如何查詢變量和它在何處能夠找到變量的規(guī)則。詞法作用域的關(guān)鍵性質(zhì)是,它是在代碼編寫時(shí)被定義的(假定你不使用eval()with作弊的話)。

動(dòng)態(tài)作用域看起來在暗示,有充分的理由,存在這樣一種模型,它的作用域是在運(yùn)行時(shí)被確定的,而不是在編寫時(shí)靜態(tài)地確定的。讓我們通過代碼來說明這樣的實(shí)際情況:

function foo() {
    console.log( a ); // 2
}

function bar() {
    var a = 3;
    foo();
}

var a = 2;

bar();

foo()的詞法作用域中指向a的RHS引用將被解析為全局變量a,它將導(dǎo)致輸出結(jié)果為值2。

相比之下,動(dòng)態(tài)作用域本身不關(guān)心函數(shù)和作用域是在哪里和如何被聲明的,而是關(guān)心 它們是從何處被調(diào)用的。換句話說,它的作用域鏈條是基于調(diào)用棧的,而不是代碼中作用域的嵌套。

所以,如果JavaScript擁有動(dòng)態(tài)作用域,當(dāng)foo()被執(zhí)行時(shí),理論上 下面的代碼將得出3作為輸出結(jié)果。

function foo() {
    console.log( a ); // 3  (不是 2!)
}

function bar() {
    var a = 3;
    foo();
}

var a = 2;

bar();

這怎么可能?因?yàn)楫?dāng)foo()不能為a解析出一個(gè)變量引用時(shí),它不會(huì)沿著嵌套的(詞法)作用域鏈向上走一層,而是沿著調(diào)用棧向上走,以找到foo()從何處 被調(diào)用的。因?yàn)?code>foo()是從bar()中被調(diào)用的,它就會(huì)在bar()的作用域中檢查變量,并且在這里找到持有值3a。

奇怪嗎?此時(shí)此刻你可能會(huì)這樣認(rèn)為。

但這可能只是因?yàn)槟銉H在擁有詞法作用域的代碼中工作過。所以動(dòng)態(tài)作用域看起來陌生。如果你僅使用動(dòng)態(tài)作用域的語言編寫過代碼,它看起來就是很自然的,而詞法作用域?qū)⑹莻€(gè)怪東西。

要清楚,JavaScript 實(shí)際上沒有動(dòng)態(tài)作用域。它擁有詞法作用域。簡(jiǎn)單明了。但是this機(jī)制有些像動(dòng)態(tài)作用域。

關(guān)鍵的差異:詞法作用域是編寫時(shí)的,而動(dòng)態(tài)作用域(和this)是運(yùn)行時(shí)的。詞法作用域關(guān)心的是 函數(shù)在何處被聲明,但是動(dòng)態(tài)作用域關(guān)心的是函數(shù) 從何處 被調(diào)用。

最后:this關(guān)心的是 函數(shù)是如何被調(diào)用的,這揭示了this機(jī)制與動(dòng)態(tài)作用域的想法有多么緊密的關(guān)聯(lián)。要了解更多關(guān)于this的細(xì)節(jié),請(qǐng)閱讀 “this與對(duì)象原型”。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容