編輯:謝謝你的答案,我想我現在得到它。它需要了解範圍和提升。下面是一個新實例,我認爲示出兩個孔:如果函數的詞法環境是在函數被定義時創建的,那麼爲什麼可以在函數之後聲明一個自由變量?
var a = function(){
alert(x);
}
var x = 1;
(function(){
var x = 2;
a();
})();
上述警告1.詞彙範圍由以下事實:這個警報1和不是2,並且曳引由以下事實說明示出的是「無功x = 1「行後用」alert(x)「聲明匿名函數並定義。據稱,起重裝置,上述等效於以下(來源:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html):
var x;
var a = function(){
alert(x);
}
x = 1;
(function(){
var x = 2;
a();
})();
所以由於x被有效地初始化函數定義之前,在X「警報(X)」是相同X,其隨後被設置爲1。
由於JS使用詞法作用域,行「VAR X = 2」不覆蓋與一個相關聯的X。
這是對的嗎?
---原題---
我花了幾乎一整天試圖弄清楚這一點。我已經閱讀了一些關於範圍和關閉Javascript的文章,但這仍然沒有我。
我被告知,函數的詞法環境是在定義函數時創建的,而不是在執行時創建的。
所以,如果沒有名爲X在我的程序的任何地方聲明的變量,那麼什麼是匿名函數封閉環境當我做到這一點?:
var a = func(){
var y = 7; //just for illustrative purposes
alert(x);
});
到點我理解是環境是變量名稱到值的映射......所以它將是
y: 7
x: ?
這是正確的嗎?下面的代碼警報「10」:
(function(){
var a = function(){
alert(x);
};
var x = 10;
a();
})();
我的猜測是,當一個被調用時,JS檢查封閉環境爲X的映射,仍然沒有找到,接着檢查當地環境並通過「var x = 10」將x設置爲10。是對的嗎?
如果是這樣的話,那麼我希望下面還要工作的,但它並不:
var a = function(){
alert(x);
};
(function(){
var x = 10;
a();
})();
我會希望出現的情況是,當執行一個和「警報(X);」運行時,它會檢查關閉環境x,找不到,然後檢查「var x = 10」所在的外部環境,並找到x。但相反,我得到一個錯誤,沒有定義x。
如果我能夠知道當設置的最初定義的匿名函數是最初定義的時候解釋器做了什麼「準備工作」,也就是說,當口譯人員在「alert(x)」中遇到x時。
感謝
好問題。答案是詞法和動態範圍的區別。 Javascript並沒有真正的後者,除了全局變量 –
IIFE創建了一個局部範圍,這就是爲什麼最後一個不起作用,IIFE的工作方式稍有不同,更像變量。 – adeneo
@NiklasB。那麼一個函數的詞法範圍就包含了它的定義之後發生了什麼,也就是說,當「var x = 10」發生在函數的定義之後,但是在相同的「深度」時,它實際上是在修改函數的詞法範圍? – user3391564