gpt4 book ai didi

javascript - 有人可以向我解释一下这个匿名函数数组的作用域是如何工作的吗?

转载 作者:行者123 更新时间:2023-11-28 20:07:25 31 4
gpt4 key购买 nike

很简单,我想知道为什么对 arr0 的调用似乎拖入了 i 的值,而不是存储在函数中该位置的值。

<script>
var arr = [];

for(var i = 0; i < 3; i++) {
//Assign anonymous functions to the array in positions 0 to 2
arr[i] = function() { console.log("function " + i); }
}

for(var i = 0; i < 3; i++) {
//The output for these function calls is correct!
arr[i]();
}

//Here I expected to output: function 0, but instead outputs: function 3 WTF!
arr[0] ();

</script>

这是输出:

function 0
function 1
function 2
function 3

对于最后一次调用,即:arr[ 0 ] ();我预计输出是“function 0”,但令人惊讶的是它不是......可以请有人解释一下原因吗?

提前致谢!

最佳答案

嗯,这是一个混合体......

您正在使用放置在全局范围内的相同 i 变量(尽管在第二个循环中“重新定义”了它,但它仍然是相同的 i)

因此,在第二个循环中,每次迭代都会更改该 global i 的值,从而导致

function 0
function 1
function 2

function 3

输出。

顺便说一句,如果您在第二个循环中使用k,这绝对不是预期的结果:

<script>
var arr = [];

for(var i = 0; i < 3; i++) {
//Assign anonymous functions to the array in positions 0 to 2
arr[i] = function() { console.log("function " + i); }
}

for(var k = 0; k < 3; k++) {
//The output for these function calls is correct!
arr[k]();
}

//Here I expected to output: function 0, but instead outputs: function 3 WTF!
arr[0] ();

</script>

这会产生:

function 3 
function 3
function 3

function 3

这就是上面链接(评论中)提到的臭名昭著的循环问题

原因是在第一个循环中定义的函数(顺便说一句,在一般情况下您应该尽量避免)“关闭”与其定义相同范围内的变量 - i 在这种情况下。这意味着以后每当 i 的值发生更改时,它都会反射(reflect)在该函数中。

最后一个示例显示了它的实际效果 - ifirst for 循环更改,因此当循环完成时 - 它的值是3。您定义的所有函数现在都具有相同的i 值 - 3

要使输出像这样:

function 0
function 1
function 2
function 0

你可以做到这一点(并不是说它那么好,结构明智):

var arr = [];

for(var i = 0; i < 3; i++) {
//Assign anonymous functions to the array in positions 0 to 2
arr[i] = (function(index){ return function() { console.log("function " + index); };}(i));
}

for(var k = 0; k < 3; k++) {
//The output for these function calls is correct!
arr[k]();
}

//Here I expected to output: function 0, but instead outputs: function 3 WTF!
arr[0] ();

这会产生所需的结果。

在这里,您定义一个匿名函数:

(函数(索引){ ... }(i))

立即以 i 作为参数调用。该参数在函数体中被称为 index (并不是说它很重要,即使您仍然将其称为 i - 它会起作用,因为“内部”i 会遮蔽“外部”的)。

该函数返回一个在 index 上具有不同闭包的函数,这并不重要,因为在立即调用的函数存在后 index 不可用。

另一种方法是使用某种迭代器 - map,如果支持的话,就可以了。

关于javascript - 有人可以向我解释一下这个匿名函数数组的作用域是如何工作的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20557817/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com