js中for循環變量的作用域
今天在網上看到一個前端的面試題就想做做,題目如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>MR_LP --> QQ :3206064928</title>
</head>
<body>
</body>
<script type="text/javascript" charset="utf-8">
var data = [];
for(var k = 0; k < 3; k++){
data[k] = function(){
console.log(k);
};
}
data[0]();
data[1]();
data[2]();
</script>
</html>
猜猜這段代碼輸出結果是什麼?
在沒有實踐前原來心裏以爲就是0,1,2咯,不過暗想沒有那麼簡單,就把這個代碼敲了下,結果控制檯輸出如下:
想了半天都沒有理解爲什麼,在查找資料之後才知道,由於for循環不是不是在一個方法體中,所以for循環中的k是a同級的變量,即全局變量,最終循環結束,k保存在內存中不會馬上銷燬,所以你在for循環結束的時候輸入k可以看到k=3;
而 data[k] = function(){
console.log(k);
};在for循環中相當於閉包,data[0]、data[1]、data[2] 函數內的變量k實際都是指向同一個地址,所以輸出的值都是一樣的。
不過值得注意的是,如果在for循環中聲明變量爲let的話,則輸出的值則爲 0、1、2,因爲let是嚴格模式,聲明的變量只在let命令所在的代碼塊有效果,也就是只有在for循環中有效,所以如果你把代碼改成:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>MR_LP --> QQ :3206064928</title>
</head>
<body>
</body>
<script type="text/javascript" charset="utf-8">
var data = [];
for(let k = 0; k < 3; k++){
data[k] = function(){
console.log(k);
};
}
console.log("k="+k);
data[0]();
data[1]();
data[2]();
</script>
</html>
運行的時候控制檯就會報錯如下: