为什么数组上的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示例。