//Lets start with a basic Javascript snippet
function generateCash() {
var denomination = [];
for (var i = 10; i < 40; i += 10) {
denomination.push(i);
}
return denomination;
}
這在Javascript基本功能語句返回的[10,20,30]
//--Lets go a step further
function generateCash() {
var denomination = [];
for (var i = 10; i < 40; i += 10) {
denomination.push(console.log(i));
}
return denomination;
}
陣列這將打印10,20,30 sequentialy作爲循環迭代,但會返回一個[undefined,undefined,undefined]的數組,主要原因是我們沒有推送i的實際值,我們只是將其打印出來,因此在每次迭代時javascript引擎都會將其設置爲undefined。
//--Lets dive into closures
function generateCash() {
var denomination = [];
for (var i = 10; i < 40; i += 10) {
denomination.push(function() {
console.log(i)
});
}
return denomination;
}
var dn = generateCash();
console.log(dn[0]());
console.log(dn[1]());
console.log(dn[2]());
這有點棘手,你期望輸出是什麼,它會是[10,20,30]?答案是否定的,讓我們看看這是怎麼發生的。首先創建一個全局執行上下文,當我們創建dn時,我們也有generatecash()函數。現在我們看到,隨着for循環的迭代,它創建了三個匿名函數對象,可能會想到push函數中的console.log也被觸發了,但事實上並非如此。我們調用了generateCash(),所以push函數只是創建了三個匿名函數對象,它不會觸發函數。在迭代結束時,當前的本地上下文從執行堆棧中彈出,並且它離開i:40和arr:[functionobj0(),functionob1(),functionobj2()]的狀態。
所以當我們開始執行最後三條語句時,它們都輸出40,因爲它無法從當前範圍中獲取i的值,所以它會上升到範圍鏈並發現i的值有被設置爲40.他們之所以會激發40的原因是因爲dn的每個組件都在同一個執行上下文中,並且他們都無法在當前範圍中找到i的值,所以它們會上升到範圍鏈並發現我設置爲40,並分別輸出它
[「var functionName = function(){}」與「function functionName(){}」in Javascript]中的可能重複(http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname-in-javascript) – BrunoLM 2010-10-11 01:56:35
@BrunoLM:我認爲這是一個不同的問題。 – Thilo 2010-10-11 02:01:54
@Thilo:同樣的答案適用。 – BrunoLM 2010-10-11 02:02:19