作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中的任何变量的最后一个值。别忘了闭包所保存的时整个变量对象,而不是某个特殊的变量。下面这个例子可以清晰地说明这个问题:
function createFunction () {
ar result = new Array();
for (var i = 0; i < 10; i++) { // 虽然现在用let可以解决这个问题
result[i] = function() {
return i;
}
}
return result;
}
这个函数返回的函数数组中,所有函数的内部 i 的值都是10,但是我们可以通过创建另一个匿名函数强制让闭包的行为符合预期:
function createFunctions(){
var result = new Array();
for (let i = 0; i < 10; i++) {
result[i] = function(num) {
return function() {
return num;
}
}(i)
}
return result;
}
在这里我们没有直接把闭包直接赋值给数组,儿时定义了一个匿名函数,并将立即执行该匿名函数的结果赋值给数组。这里的匿名函数有一个参数num,也就是最终的函数要返回的值。在调用每个匿名函数时,我们传入了变量i。由于函数参数时按值传递的,所以就会将变量i的当前值复制给参数num,而在这个匿名函数中又创建并返回了一个访问num的闭包。这样一来。result的值就符合预期了。
上期链接:https://blog.csdn.net/JohnZhongJob/article/details/100565951