var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
请问为什么a[6]()会等与10呢?
不应该是在遍历的时候就已经把值给a了吗?
像是这样:
a[0]=function(){
console.log(0);
}
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
你可以这么理解,i变量提升到最上面。
个人认为要根据作用域来查找定义的变量,函数内部没有定义,就要往他的上级作用域查找,而for循环是瞬间完成的(你就把循环的速度想的极快吧,反正要比调用的函数快),所以答案是10;
这个还是闭包的问题嘛,function这个函数只是定义而已,没有运行,运行的时候才回去找i的值。
楼上正解,的却是每次都赋值了,但是赋值的是个函数吖,这是关键,函数中的变量最后的却是10,所以。。。。
你可以这么理解:
因为i是在a[i]函数外定义的,所以函数内获取的值是i最终的值。
就好比,你i=1,i=2,...,i=10,虽然你操作了这么多次,最后一次是10.
这涉及到一些闭包的知识。
如果你想要得到,1,2,3,...,10这样的结果,可以修改为这样:
循环的过程并未执行console.log(i)这个方法,只是把这个方法放到了数组里面,循环结束时i仍然是个变量,但被赋值为10。i等于10的时候并未执行循环,所以不要理解为i应该等于9。此时执行a6了。6指的是数组里的第六个元素,而i已经说过是10了,所以就输出10了。
如果怕复杂就不要把变量提升和闭包弄进来,只是单纯看循环比较好理解一点。
整个作用域中只有一个i,因此i停留在最后一个值10
ES6中更加符合你直觉的定义方式为
let(块级作用域)而非var(函数作用域)所有闭包中的
i都指向一个东西,所以for循环修改i之后,闭包中的i也跟着改。es5的折衷办法就是
bind掉闭包中的i,因为i是原生类型,所以会传值。这种方法也不用什么es6,也不用构建更高阶的函数。因为函数执行的是
但是函数中没有定义
var i, 往作用域链外层(上层)寻找var i;得到
for循环里面的定义var i,你执行函数的时候,for循环已经完成,i是等于10的,所以结果是10;