这是一小段代码,我觉得闭包函数有一种奇怪的行为......
var arr = [5, 6, 7, 8, 9, 0];
var someFn;
arr.forEach(function(val, idx) {
if (!someFn) {
someFn = function() {
console.log(`B: ${idx} : ${val}`);
};
}
console.log(`A: ${idx} : ${val}`);
someFn();
});

最终的控制台输出是......
A: 0 : 5 B: 0 : 5 A: 1 : 6 B: 0 : 5 A: 2 : 7 B: 0 : 5 A: 3 : 8 B: 0 : 5 A: 4 : 9 B: 0 : 5 A: 5 : 0 B: 0 : 5
我希望someFn
在forEach处理时处理增量值,但它总是输出第一个值"idx: 0, val: 5"
。
我不认为这是正确的行为,因为someFn
正在创建一个封闭变量idx
和val
的闭包,并且这两个变量在外部函数中都在变化。
感谢有人能够解释这种行为。
答案 0 :(得分:0)
根据这个问题other answer:
闭包是一个堆栈帧,在函数开始执行时分配...
因此每个函数调用都会创建自己的闭包。
forEach
做的是它需要一个函数(回调)并多次调用它(从数组中传递元素及其索引和数组)。因此,forEach
的每次迭代都会创建一个新的闭包。
您在第一次迭代时定义someFn
(之后永远不会重新声明),因此它被捕获的闭包是第一次迭代的闭包。因此,唯一可用的值是第一次迭代的值。
闭包与函数本身无关,与调用有关。
示例:
function theFunction(value) {
return function() {
return value;
};
}
var someFn1 = theFunction("Ibrahim");
var someFn2 = theFunction("John");
console.log("someFn1: ", someFn1());
console.log("someFn2: ", someFn2());

在示例中,每次调用theFunction
都会创建一个新的闭包。 someFn1
和someFn2
,虽然它们是由相同的功能生成的,但无法访问相同的关闭。
代码中等效于theFunction
的是传递给forEach
的同义函数,它被执行(因此创建clousures)的次数与数组中的元素一样多。
答案 1 :(得分:0)
我希望
someFn
创建一个封闭变量idx
和val
的闭包,这两个变量在外部函数中都在变化。
不,他们不会改变。它们是每次调用外部函数时实例化的新变量。第一次迭代中的两个变量,在那里创建的闭包确实关闭,保持它们的值。
要获得预期的行为,可以使用没有函数的循环,只需要声明两个变量:
var arr = [5, 6, 7, 8, 9, 0];
for (var [idx, val] of arr.entries()) {
// ^^^^^^^^^^^^^^ global variables
if (!someFn) {
var someFn = function() {
console.log(`B: ${idx} : ${val}`);
};
}
console.log(`A: ${idx} : ${val}`);
someFn();
}