2017-06-25 123 views
0

當我用下面的代碼:JavaScript中的範圍鏈是什麼?

function a(){ 
    var q = 1; 
    function b(){ 
    console.log(q); 
    } 
b(); 
} 

var q= 2; 
a(); 

它給我輸出1 但是當我用下面的代碼:

function b(){ 
    console.log(q); 
} 

function a(){ 
    var q = 1; 
b(); 
} 

q= 2; 
a(); 

輸出爲2 。當我使用下面的代碼:

function a(){ 
    function b(){ 
    console.log(q); 
    } 
b(); 
} 

var q= 2; 
a(); 

再次我輸出我知道那是什麼,因爲我在谷歌搜索,但沒有完全瞭解相關的作用域鏈。

+0

。請使用代碼標籤在寫這個問題的部分代碼,使EASI呃閱讀代碼。 – ssharma

+0

你已經過分簡化了每個例子,因爲它們中沒有一個產生任何輸出,因爲'b()'從來沒有被調用過。請創建一個[mcve],它實際上再現了您的問題 – charlietfl

+0

抱歉,我現在已更正它 – Aniket

回答

0

作用域鏈僅僅是聲明標識符的位置,這些標識符被搜索以解析標識符的值。

它區分其中東西被宣佈與一些聲明是非常重要的。僅僅因爲您在使用q的函數調用之前聲明q並不意味着這是將被使用的q--可能有多個q變量,每個變量都存在它們自己的範圍。

在我們看看你的例子之前,想象一下這個場景。你在一個大房間裏,被分成兩個工人足夠大的隔間。你和你的同事「喬」共用一個隔間(因爲你在那裏,這是你的本地範圍,你可以與喬共享)。如果你和喬同時坐在你的共用隔間裏,而你想和喬聊聊,你只會說「嘿喬」,喬會立即迴應。但是,如果喬起牀在辦公室的水冷卻器裏拿些水怎麼辦?如果您之後說「嘿喬」,他不會在您的小臥室範圍內找到,所以您必須將搜索範圍擴大到整個辦公室(包含您的小臥室所在範圍的更高範圍)。但是,通過將搜索範圍擴大到更高的範圍(沿着範圍鏈),你最終會找到喬。現在想象一下,在同一樓層的兩個辦公室之間共用冷水機。你不會在你的房間裏找到喬,他不會在你的辦公室,所以你不得不再次擴大你的搜索範圍,以包括你可見的其他範圍(隔壁的辦公室)。

還在我身邊嗎?現在,這裏有一個皺紋......如果在每個位置都有不同的「Joe's」,而你想與之交談的Joe在另一個辦公室?當你說「嘿喬!」時,最近的人會回答,但那可能不是你想到的喬。這就是你的q變量的情況。你有不止一個在不同的範圍級別聲明,你期望的不是最接近你所調用範圍的範圍。

function a(){ 
 
    // q is declared in this scope and this is the next highest scope to where it is 
 
    // used for the console.log, so 1 is the output 
 
    var q = 1; 
 
    function b(){ 
 
    // q isn't declared in this function's scope, so the next higher scope 
 
    // needs to be checked. 
 
    console.log(q); 
 
    } 
 
b(); 
 
} 
 

 
// Even though this code runs just before the function call, 
 
// this is creating a different "q" variable in the higest scope 
 
// -- the global scope. When the function runs, it won't need 
 
// to search all the way up to this level to find a declaration 
 
// for q, so 2 isn't what is outputted 
 
var q= 2; 
 

 
// Now, run the function 
 
a();

function b(){ 
 
    // Here, there is no q in this local scope, 
 
    // so again, the next highest scope is searched. 
 
    // Since this is NOT a nested function, the next highest 
 
    // scope is the global scope and the q in that scope is found 
 
    // producing 2 as output 
 
    console.log(q); 
 
} 
 

 
function a(){ 
 
// Create a local q variable that only is accessible from here 
 
var q = 1; 
 
    
 
// Invoke the b function 
 
b(); 
 
} 
 

 
// Global q is being set 
 
q = 2; 
 

 
// Invoke the a function 
 
a();

function a(){ 
 
    // There is no q in this scope, so the next highest scope (the global scope) 
 
    // is checked. 
 
    function b(){ 
 
    // There is no q in this scope, so the scope of a is checked 
 
    console.log(q); 
 
    } 
 
    b(); 
 
} 
 

 
// Not only is this the Global q, but it's the only q declared 
 
var q= 2; 
 
a();