面试题情景:
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
a[7](); // 10
a[8](); // 10
a[9](); // 10
这里好像和想的不那么一样,但是js就是这样,i就是全局变量,所以用来计数的循环变量泄露为全局变量。上面代码中,变量i是var声明的,在全局范围内都有效。所以每一次循环,新的i值都会覆盖旧值,导致最后输出的是最后一轮的i的值。也可以这样来讲,循环的时候i是没有赋值的,所以a中的值就是function () {console.log(i);};,最终i等于10,所以每次调用输出的都是10.
如果我想输出的是0-9呢?
那么就应该这样:
var a = [];
for(var i=0;i<10;i++){
a[i]=(function(o){return function(){console.log(o)}})(i);
}
今天我在看let的时候,let为JavaScript新增了块级作用域,用它所声明的变量,只在let命令所在的代码块内有效。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
我又看了看它编译成es5的样子,这道面试题又多了两个方法,其实重在理解es6的块级作用域和原来的全局作用域。
"use strict";
var a = [];
var _loop = function (i) {
a[i] = function () {
console.log(i);
};
};
for (var i = 0; i < 10; i++) {
_loop(i);
}