ser*_*ner 5 javascript arrays mapping mutable immutability
当最初的目的是创建一个新数组时,为什么map方法会改变原始数组?
我有一个对象数组,我传递给一个纯函数,然后映射给定的数组并返回一个新的.然后我注意到原始数组也被改变了.我理解Js中的Object通过引用传递的概念,但是仍然无法抓住为什么实现map会改变原始数组,有点胜过IMO的目的.
var initialArray = [ { name: 'one' }, { name: 'two' }, { name: 'three'} ];
function doSomething(array) {
// lodash
// return _.map(array, (item) => _.assign(item, {isSelected: true}));
// vanilla
return array.map(function(item) {
item['isSelected'] = true;
return item
});
}
var changedArray = doSomething(initialArray);
console.log('initialArray', initialArray); // [{ name: 'one', isSelected: true }, ...]
console.log('changedArray', changedArray); // [{ name: 'one', isSelected: true }, ...]
console.log(initialArray === changedArray); // false
Run Code Online (Sandbox Code Playgroud)
首先我想了解为什么会这样?
第二个我喜欢理解如何在不改变原始数组的情况下映射数组?(即._cloneDeep每次map做错之前都做过)
提前致谢 !
好吧,据我所知,这就是事情的真实情况.我想我可能因某种原因有更高的期望,但在Js中可以解释,所以至少存在一定的一致性.
我能想到的用于创建具有新成员的新阵列的最优雅的解决方案是
return _.map(array, (item) => _.assign({}, ...item, {isSelected: true}));
Run Code Online (Sandbox Code Playgroud)
.map 将创建一个新数组,但仍会引用数组中的对象.
因此,当您在object item内部.map函数中进行更改时,它将引用输入数组中的原始对象.
修复它的一种方法是在修改每个对象之前克隆它们
var initialArray = [ { name: 'one' }, { name: 'two' }, { name: 'three'} ];
function clone(obj) {
if (null == obj || "object" != typeof obj) return obj;
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
}
return copy;
}
function doSomething(array) {
// lodash
// return _.map(array, (item) => _.assign(item, {isSelected: true}));
// vanilla
return array.map(function(item) {
var copy = clone(item);
copy['isSelected'] = true;
return copy;
});
}
var changedArray = doSomething(initialArray);
console.log('initialArray', initialArray); // [{ name: 'one'}, ...]
console.log('changedArray', changedArray); // [{ name: 'one', isSelected: true }, ...]
console.log(initialArray === changedArray); // false
Run Code Online (Sandbox Code Playgroud)
Credit:从此帖子复制克隆功能