почему карта 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})
}
но я все равно получаю тот же результат (который начинает меня вести сумасшедший.)
Я был бы очень благодарен тому, кто сможет объяснить мне, что я делаю неправильно !
спасибо
2 ответов
вы не изменяете исходный массив. Вы изменяете объекты в массиве. Если вы хотите избежать мутирования объектов в массиве, вы можете использовать Object.assign
создать новый объект со свойствами оригинала плюс любые изменения необходимо:
const freeProduct = function(products) {
return products.map(x => {
return Object.assign({}, x, {
productType: "free"
});
});
};
2018 Edit:
на большинство браузеров теперь вы можете использовать синтаксис распространения объектов вместо Object.assign
для этого:
const freeProduct = function(products) {
return products.map(x => {
return {
...x,
productType: "free"
};
});
};
чтобы уточнить ответ SimpleJ - если бы вы были === два массива, вы бы обнаружили, что они не будут равны (не тот же адрес в памяти), подтверждая, что сопоставленный массив на самом деле является новым массивом. Проблема в том, что вы возвращаете новый массив, который полон ссылок на те же объекты в исходном массиве (он не возвращает новые объектные литералы, он возвращает ссылки на тот же объект). Поэтому вам нужно создавать новые объекты, которые являются копиями старых объектов-ie, w/ объект.назначить примеру SimpleJ.