为什么此JavaScript映射不是无限循环?

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处理的元素范围是在第一次调用回调之前设置的。调用地图后开始添加到数组的元素将不会被回调访问。如果更改了数组的现有元素,则传递给回调的值将是映射访问它们时的值。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Description

因此,它的行为就像是那样设计的。除其他原因外,它还可以防止无限循环!

map是函数编程世界中的一个函数,其中不变性是重要的原则。根据此原理,如果您调用map一个输入(并且其他变量不变),您将始终获得完全相同的结果。允许修改输入会破坏不变性。


lea*_*iro 7

因为它不会使数组变异 (请参阅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构建了一个新数组,因此在不使用返回的数组时使用它是一种反模式;使用forEachfor-of代替。

您不应该使用地图的标志:

  • A)您没有使用它返回的数组,和/或

  • B)您没有从回调中返回值。