为什么数组上的js映射修改原始数组?

我很困惑的是map()的行为。

我有这样的对象的数组:

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

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

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

function是:

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

其中返回以下数组:

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

所以我重写了我的function是:

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

它按照预期返回数组。

但是! 这就是我放松的时刻,在这两种情况下我的原始产品arrays被修改。

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

我甚至试图创build一个我的数组的克隆,这样我的function

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

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

我会非常感谢任何能解释我做错什么的人!

谢谢

你并没有修改你的原始数组。 你正在修改数组中的对象。 如果你想避免改变数组中的对象,你可以使用Object.assign来创build一个新的对象,其中包含原始属性以及你需要的任何改变:

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

为了详细说明SimpleJ的答案 – 如果你想===这两个数组,你会发现它们不会相同(不是相同的地址在内存中),确认映射的数组实际上是一个新的数组。 问题是你正在返回一个新的数组,它充满了对原始数组中的SAME对象的引用(它不会返回新的对象字面值,而是返回对同一个对象的引用)。 所以你需要创build一个新的对象,这些对象是旧对象的副本 – 也就是说,由SimpleJ提供的Object.assign示例。

Interesting Posts