繁体   English   中英

如果被推送的元素不是原始元素,为什么JavaScript Array.push不使用变量

[英]Why does JavaScript Array.push not use variable if the pushed element is not a primitive

考虑这个经典的JavaScript闭包功能。 我了解封包的展示方式。 我知道内部函数会关闭变量i,即3。

我不明白的是为什么数组应该包含变量i,而我们所做的只是将函数推入数组中,而数组中我有一个来自for循环的值。

 function buildFunctions() { var arr = []; for (var i = 0; i < 3; i++) { arr.push(function() { console.log(i) }) } return arr; } var fs = buildFunctions(); // [function(){console.log(1)}, ...and so on] //not [function(){console.log(i)} ...and so on] fs[0](); // outputs 3 fs[1](); // 3 fs[2](); // 3 

否则,这将返回数组的正确(imo)内容:

function buildFunctions() {
   var arr = [];
   for (var i = 0; i < 3; i++) {
      arr.push(i)
   }
   return arr; // [0, 1, 2]
 }

arr.push(i)通过一个原始值到.push ,值012分别。 这里的值与i解除关联; 你不推i ,你推012

arr.push(function () { console.log(i) })推送一个内部引用变量的函数。 在调用函数时,该变量的值恰好是3 (👈这是要理解的关键句子。)

请注意,推函数和推数字之间没有根本区别。 两者都简单地通过值传递。 在一种情况下,值是一个数字,在另一种情况下,值是一个函数。 请参阅JavaScript是引用传递还是值传递语言?

我认为循环由于某种原因而增加了混乱。 如果展开该循环,则可能更直观。

 function buildFunctions() { var arr = []; var i = 0; arr.push(function() { console.log(i) }) i++; arr.push(function() { console.log(i) }) i++; arr.push(function() { console.log(i) }) i++; return arr; } var fs = buildFunctions(); // [function(){console.log(1)}, ...and so on] //not [function(){console.log(i)} ...and so on] fs[0](); // outputs 3 fs[1](); // 3 fs[2](); // 3 

因此,您可以看到我们正在将三个函数推入数组,而在两者之间,我们正在递增i 您还可以看到所有三个函数都在“看”相同的i变量。

调用函数之前,不会读取变量,因此,由于它们都在“看”相同的变量,因此最终调用它们时,它们自然会给出相同的结果。 而且由于在任何一次调用之前 i都增加了3倍,因此返回的值为3


作为练习,更改每个函数以在其中添加另一个i++ 您将看到,不仅它们都读取同一个变量,而且它们都可以突变相同的变量。

当您调用该函数时, i的值将变为3 ,这是arr.push内部的函数arr.push引用的。

块范围let将给您预期的结果:

 function buildFunctions() { var arr = []; for (let i = 0; i < 3; i++) { arr.push(function() { console.log(i) }) } return arr; } var fs = buildFunctions(); // [function(){console.log(1)}, ...and so on] //not [function(){console.log(i)} ...and so on] fs[0](); // 0 fs[1](); // 1 fs[2](); // 2 

我不明白的是为什么数组应该包含变量i

没有。

该数组包含三个函数。

这些函数中的每一个都关闭(相同)变量i 注: i没有价值i的时间。

您调用任何一个函数( 在循环完成之后 )时,它们都会读取该变量的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM