为什么这个 JavaScript 地图不是无限循环?
Why is this JavaScript map NOT an Infinite Loop?
我正在学习 JavaScript。我写这段代码是为了学习地图功能。但是后来我很困惑为什么这不是连续映射它,因为每个映射序列都会将一个新元素推送到数组。它不应该在映射时继续推送新元素吗? 为什么地图只对原来的三个元素运行起作用,对新推的三个元素不起作用?
我尝试在节点环境中调试它,arr
变量进入 闭包 。我知道什么是闭包,但我无法理解这里发生了什么。
let array = [1, 2, 3];
array.map((element) => {
array.push(10);
console.log(element);
});
我希望输出应该是 1,2,3,10,10,10,10,10,10,10,10......10
但实际输出只有1,2,3
.
引自MDN:
The range of elements processed by map is set before the first invocation of callback. Elements which are appended to the array after the call to map begins will not be visited by callback. If existing elements of the array are changed, their value as passed to callback will be the value at the time map visits them.
所以,它的行为是这样的,因为它就是这样设计的。它是这样设计的,除其他原因外,为了防止无限循环!
map
是函数式编程世界中的一个函数,其中不可变性是一个重要原则。根据这个原则,如果你在一个输入上调用 map
(并且其他变量不变),你将始终得到 完全 相同的结果。允许修改输入会破坏不变性。
为什么和 MDN 上看到的一模一样:
var new_array = arr.map(function callback(currentValue[, index[, array]]){}
The range of elements processed by map is set before the first invocation of callback. Elements which are appended to the array after the call to map begins will not be visited by callback.
(感谢上面来自 MDN 的 Joe post 的引用。)
一旦 map 被调用,它就会将当时的数组作为参数;一旦通过,任何更改都与先前的变量本身无关。
见下文:
let array = [1, 2, 3];
array.map((element) => {
array.push(10);
console.log(element);
});
console.log(array)
因为它不会改变数组 (参见Array.prototype.map()
)。
相反,它 returns 一个新数组,其中包含对调用数组中的每个元素调用提供的函数的结果。
在下面的代码片段中,改变 array
的是对 array.push(10);
的调用三次(原始数组中的每个元素一次),而不是 map
函数本身。
let newArray = array.map((element) => {
array.push(10); // <-- here you mutate the array
console.log(element);
});
上述文档中的重要引述(这里的关键点是):
The range of elements processed by map is set before the first
invocation of callback. Elements which are appended to the array
after the call to map begins will not be visited by callback.
在以下代码片段中,您可以看到如何正确使用地图功能的示例:
let array = [1,2,3];
let newArray = array.map(element => element + 10); // sum 10 to every element
console.log('original: ', array); // original: [1,2,3]
console.log('new one: ', newArray) // new one: [11,12,13]
最后一个想法(也来自文档),将您发布的代码作为参考:
由于 map
构建了一个新数组,当您不使用返回的数组时使用它是一个 anti-pattern;请改用 forEach
或 for-of
。
您不应该使用地图的迹象:
A) 你没有使用数组 returns, and/or
B) 您没有从回调中返回值。
我正在学习 JavaScript。我写这段代码是为了学习地图功能。但是后来我很困惑为什么这不是连续映射它,因为每个映射序列都会将一个新元素推送到数组。它不应该在映射时继续推送新元素吗? 为什么地图只对原来的三个元素运行起作用,对新推的三个元素不起作用?
我尝试在节点环境中调试它,arr
变量进入 闭包 。我知道什么是闭包,但我无法理解这里发生了什么。
let array = [1, 2, 3];
array.map((element) => {
array.push(10);
console.log(element);
});
我希望输出应该是 1,2,3,10,10,10,10,10,10,10,10......10
但实际输出只有1,2,3
.
引自MDN:
The range of elements processed by map is set before the first invocation of callback. Elements which are appended to the array after the call to map begins will not be visited by callback. If existing elements of the array are changed, their value as passed to callback will be the value at the time map visits them.
所以,它的行为是这样的,因为它就是这样设计的。它是这样设计的,除其他原因外,为了防止无限循环!
map
是函数式编程世界中的一个函数,其中不可变性是一个重要原则。根据这个原则,如果你在一个输入上调用 map
(并且其他变量不变),你将始终得到 完全 相同的结果。允许修改输入会破坏不变性。
为什么和 MDN 上看到的一模一样:
var new_array = arr.map(function callback(currentValue[, index[, array]]){}
The range of elements processed by map is set before the first invocation of callback. Elements which are appended to the array after the call to map begins will not be visited by callback.
(感谢上面来自 MDN 的 Joe post 的引用。)
一旦 map 被调用,它就会将当时的数组作为参数;一旦通过,任何更改都与先前的变量本身无关。
见下文:
let array = [1, 2, 3];
array.map((element) => {
array.push(10);
console.log(element);
});
console.log(array)
因为它不会改变数组 (参见Array.prototype.map()
)。
相反,它 returns 一个新数组,其中包含对调用数组中的每个元素调用提供的函数的结果。
在下面的代码片段中,改变 array
的是对 array.push(10);
的调用三次(原始数组中的每个元素一次),而不是 map
函数本身。
let newArray = array.map((element) => {
array.push(10); // <-- here you mutate the array
console.log(element);
});
上述文档中的重要引述(这里的关键点是):
The range of elements processed by map is set before the first invocation of callback. Elements which are appended to the array after the call to map begins will not be visited by callback.
在以下代码片段中,您可以看到如何正确使用地图功能的示例:
let array = [1,2,3];
let newArray = array.map(element => element + 10); // sum 10 to every element
console.log('original: ', array); // original: [1,2,3]
console.log('new one: ', newArray) // new one: [11,12,13]
最后一个想法(也来自文档),将您发布的代码作为参考:
由于 map
构建了一个新数组,当您不使用返回的数组时使用它是一个 anti-pattern;请改用 forEach
或 for-of
。
您不应该使用地图的迹象:
A) 你没有使用数组 returns, and/or
B) 您没有从回调中返回值。