[英]how to extend array.push() in javascript such that after calling push method, element should not get pushed into the array?
[英]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
,值0
, 1
和2
分别。 这里的值与i
解除关联; 你不推i
,你推0
, 1
和2
。
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.