1 回答

TA貢獻(xiàn)2012條經(jīng)驗(yàn) 獲得超12個(gè)贊
我試著把問題分析得詳細(xì)一點(diǎn),通過舉例子的方式把問題講清楚:
首先這個(gè)問題如三樓所說,不涉及閉包,主要涉及的是作用域問題,下面一步一步來看
例1:
console.log(i); // undefined
console.log(j); // undefined
for (var i = 0; i < 4; i++) {
var j = 100;
}
console.log(i); // 4
console.log(j); // 100
先看例1,第一次打印i與j都是undefined(因?yàn)闆]有定義),而第二次卻有值了,這是因?yàn)樵趂or循環(huán)內(nèi)沒有自己的作用域(在es5中只有function有自己的作用域),即是說在for內(nèi)部定義的變量的作用域不僅限于for內(nèi)部,外部照樣能訪問。
例2:
var x;
console.log(x); // undefined
var y = 200;
var y;
console.log(y); // 200
看例2,
變量x使用var聲明,但沒有被賦值,所以結(jié)果為undefined;
變量y使用var聲明并賦值,所以這時(shí)候y的值為200,
再使用var重新聲明一次,這時(shí)候原來的變量y應(yīng)該是被清除掉了,并重新定義一個(gè)新的y,因?yàn)闆]有被賦值,所以此時(shí)y應(yīng)該是undefined,但結(jié)果卻是200
這說明在同個(gè)作用域內(nèi),使用var多次聲明同一個(gè)變量名,并不會(huì)把原有變量從內(nèi)存中移除并重新分配內(nèi)存,而是繼續(xù)使用原有的內(nèi)存地址,即是說在同個(gè)作用域內(nèi),同一個(gè)變量名只能被var聲明一次,后面的var不起作用。
明白了上面兩點(diǎn)后,再來看題主的第一段代碼
var arr = [ { name: '張三1'},
{ name: '張三2' },
{ name: '張三3' },
{ name: '張三4' } ];
for ( var i = 0; i < arr.length; i++) {
arr[ i ].sayHello = function () {
console.log(i);
};
}
arr[0].sayHello(); // 4
arr[1].sayHello(); //4
這段代碼只有一個(gè)作用域(因?yàn)閒or沒有自己的作用域呀),所以在for內(nèi)部聲明的i也屬于這個(gè)作用域,并且整段代碼下來只有一個(gè)名為i的變量,所以console.log(i)這里打印的始終是同一個(gè)變量i,for循環(huán)后i變?yōu)?,所以打印結(jié)果始終是4
再看題主的第二段代碼
var arr = [ { name: '張三1'},
{ name: '張三2' },
{ name: '張三3' },
{ name: '張三4' } ];
for ( var i = 0; i < arr.length; i++) {
// arr[ i ] 綁定方法
arr[ i ].sayHello = function () {
// 打印名字
console.log(i);
};
}
for ( var i = 0; i < arr.length; i++ ) {
arr[ i ].sayHello(); // 0, 1, 2, 3
}
這段代碼也是只有一個(gè)作用域,同樣整段代碼也是只有一個(gè)名為i的變量,不同的是在第二個(gè)for循環(huán)里,每次循環(huán)都改變了這個(gè)變量i的值,改變之后再打印這個(gè)i,當(dāng)然結(jié)果就是改變后的值了,即0, 1, 2, 3了
添加回答
舉報(bào)