为什么一个数组上的js映射会修改原来的数组?

新手上路,请多包涵

我对 map() 的行为感到很困惑。

我有一组这样的对象:

 const products = [{
    ...,
    'productType' = 'premium',
    ...
}, ...]

我将这个数组传递给一个函数,该函数应该返回相同的数组但所有产品都是免费的:

 [{
    ...,
    'productType' = 'free',
    ...
}, ...]

功能是:

 const freeProduct = function(products){
    return products.map(x => x.productType = "free")
}

它返回以下数组:

 ["free", "free", ...]

所以我重写了我的函数:

 const freeProduct = function(products){
    return products.map(x => {x.productType = "free"; return x})
}

它按预期返回数组。

但 !这就是我失去理智的时刻,在这两种情况下,我的原始产品数组都被修改了。

map() 周围的文档说它不应该( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map )。

我什至尝试创建一个数组的克隆,将我的函数变成这样:

 const freeProduct = function(products){
    p = products.splice()
    return p.map(x => {x.productType = "free"; return x})
}

但我仍然得到相同的结果(这开始让我发疯)。

我将非常感谢任何可以向我解释我做错了什么的人!

谢谢你。

原文由 Edwin Joassart 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 249
2 个回答

您没有修改原始数组。您正在修改数组中的对象。如果您想避免改变数组中的对象,您可以使用 Object.assign 创建一个具有原始属性的新对象以及您需要的任何更改:

 const freeProduct = function(products) {
  return products.map(x => {
    return Object.assign({}, x, {
      productType: "free"
    });
  });
};

2018年编辑:

大多数浏览器 中,您现在可以使用对象扩展语法而不是 Object.assign 来完成此操作:

 const freeProduct = function(products) {
  return products.map(x => {
    return {
      ...x,
      productType: "free"
    };
  });
};

原文由 SimpleJ 发布,翻译遵循 CC BY-SA 4.0 许可协议

详细说明 SimpleJ 的答案 - 如果您 === 这两个数组,您会发现它们不相等(内存中的地址不同),确认映射数组实际上是一个新数组。问题是你要返回一个新数组,它充满了对原始数组中相同对象的引用(它不是返回新的对象文字,而是返回对同一对象的引用)。因此,您需要创建新对象,这些新对象是旧对象的副本——即,使用 SimpleJ 给出的 Object.assign 示例。

原文由 user5004821 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题