【问题标题】:Why does this map function not mutate the values in the original array?为什么这个 map 函数不会改变原始数组中的值?
【发布时间】:2018-01-09 11:00:45
【问题描述】:

这里是有问题的代码:

const array = [
  1, 2, 3
]

array.map(item => {
  item = item + 1
})

console.log(array)

我认为map 方法中的item(第一个)参数是对数组中原始项的引用,并且直接对其进行变异会改变第一个数组的内容......是不是真的吗?

【问题讨论】:

  • 如果你想mutate数组中的每一项,你可以使用'forEach',然后在每个元素上调用一个mutating方法。当您执行item = item+1 时,无论您调用.map 还是.forEach,您都不会改变item,因为您只是重新分配了一个局部变量。

标签: javascript arrays ecmascript-6


【解决方案1】:

map函数返回一个新数组,它不会改变原来的数组。

itemarrow function item => {...} 中的局部变量。赋值item = item + 1 不会更改原始元素,而是更改item 局部变量。

如果您想更改元素forEach 函数效率更高,因为它不会创建新数组:

array.forEach((item, index) => {
    array[index] = item + 1;
});

【讨论】:

  • OP 不关心返回值。想象一下这段代码用一个更复杂的对象代替了item。然后你可以做item.someproperty = 1 - 这就是OP要问的问题。
  • @JamesThorpe 你能在 JavaScript 中重载 operator+ 吗?
  • 没有。而且由于事物是按值复制的方式,item 将只能在本地更新,因为它是一个原语。如果它是一个更复杂的对象,您可以更改该对象的属性,但不能用完全不同的对象替换它。
  • @JamesThorpe 我不确定您的 cmets 与这段特定代码的相关性如何。您正在讨论其他事情。
【解决方案2】:

您的数组包含 原始类型 元素(此处为整数)。原始类型的变量不能通过其引用进行变异。例如,如果您的数组元素是对象,则可能发生变异,如下所示:

var array = [{val: 1}, {val: 2}, {val: 3}];
array.map(item => {item.val = item.val + 1});
console.log(array);

【讨论】:

  • 那么,你是说如果那不是原始类型数组,那么赋值会改变原始元素?
  • 为什么要这样使用地图?如果你不打算对返回的数组做任何事情,那么你应该使用 forEach。
  • @Jonah 是的,forEach 完成了这项工作,但 OP 要求提供地图,并想知道地图是否会出现突变
  • @Jonah 你错了。回调函数的变量总是引用数组中的原始项。如果更改此变量,则如果它不是原始类型,则数组中的原始值也会更改,因为引用。引用因代码 item = item + 1 的重新分配而丢失。例如,对于数组中的对象,原始更改为 map,就像我在我的答案示例中显示的那样
  • @Jonah 通过执行 item = item + 1,您可以重新分配和松散参考。即使使用对象,如果您重新分配,您也会失去参考并且原件不会发生变异
【解决方案3】:

Mozilla 说;

map() 方法使用调用的结果创建一个新数组 在调用数组中的每个元素上提供函数。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

因此,map 函数不会改变数组的值。

我知道你不想这样做,但你可以使用这个:

const array = [
  1, 2, 3
]

array.map((item, k) => {
  array[k] = item + 1
})

console.log(array)

【讨论】:

    猜你喜欢
    • 2019-10-14
    • 2021-11-18
    • 1970-01-01
    • 2019-06-25
    • 2019-07-27
    • 2021-10-17
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    相关资源
    最近更新 更多