Exp*_*oob 9 javascript arrays closures array-push map-function
我正在学习JavaScript。我写了这段代码来学习map函数。但是后来我感到困惑,为什么为什么不连续映射它,因为每个映射序列都会将一个新元素推入数组。它不应该在映射过程中继续推动新元素吗?为什么map函数仅对原始的三个元素运行,而对新的推入元素不运行?
我试图在节点环境中对其进行调试,并且该arr
变量处于关闭状态。我知道闭包是什么,但我无法理解这里发生了什么。
let array = [1, 2, 3];
array.map((element) => {
array.push(10);
console.log(element);
});
Run Code Online (Sandbox Code Playgroud)
我希望输出应该是 1,2,3,10,10,10,10,10,10,10,10......10
但是实际输出仅为1,2,3
。
Joe*_*Joe 10
引用MDN:
由map处理的元素范围是在第一次调用回调之前设置的。调用地图后开始添加到数组的元素将不会被回调访问。如果更改了数组的现有元素,则传递给回调的值将是映射访问它们时的值。
因此,它的行为就像是那样设计的。除其他原因外,它还可以防止无限循环!
map
是函数编程世界中的一个函数,其中不变性是重要的原则。根据此原理,如果您调用map
一个输入(并且其他变量不变),您将始终获得完全相同的结果。允许修改输入会破坏不变性。
因为它不会使数组变异 (请参阅Array?.prototype?.map()
参考资料)。
而是返回一个新数组,该数组具有在调用数组中每个元素上调用提供的函数的结果。
在下面的代码片段中,对进行突变的array
是对array.push(10);
3次调用(原始数组中的每个元素一次),而不是map
函数本身。
let newArray = array.map((element) => {
array.push(10); // <-- here you mutate the array
console.log(element);
});
Run Code Online (Sandbox Code Playgroud)
提到的文档中的一个重要引用(这里的要点是):
的范围由地图处理的元素被设定回调的第一次调用之前。调用地图后开始添加到数组的元素将不会被回调访问。
在以下代码段中,您可以看到有关如何正确使用map函数的示例:
let newArray = array.map((element) => {
array.push(10); // <-- here you mutate the array
console.log(element);
});
Run Code Online (Sandbox Code Playgroud)
最后一个想法(也来自文档),以您发布的代码为参考:
由于map
构建了一个新数组,因此在不使用返回的数组时使用它是一种反模式;使用forEach
或for-of
代替。
您不应该使用地图的标志:
A)您没有使用它返回的数组,和/或
B)您没有从回调中返回值。