Javascript Js Array.prototype.map()恰好是可变的?

Javascript Js Array.prototype.map()恰好是可变的?,javascript,arrays,mapping,immutability,mutable,Javascript,Arrays,Mapping,Immutability,Mutable,为什么map方法在创建新数组时会改变原始数组 我有一个对象数组,我将其传递给一个纯函数,该函数依次映射给定数组并返回一个新数组。然后我注意到原来的数组也发生了变化。。我理解Js中的对象是通过引用传递的概念,但仍然不能完全理解为什么map的实现会改变原始数组,这有点超出了IMO的目的 var initialArray = [ { name: 'one' }, { name: 'two' }, { name: 'three'} ]; function doSomething(array) {

为什么map方法在创建新数组时会改变原始数组

我有一个对象数组,我将其传递给一个纯函数,该函数依次映射给定数组并返回一个新数组。然后我注意到原来的数组也发生了变化。。我理解Js中的对象是通过引用传递的概念,但仍然不能完全理解为什么
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
首先,我想了解为什么会发生这种情况

第二,我想了解如何在不改变原始数组的情况下映射数组?(即,每次在映射之前执行
。\u cloneDeep
都感觉不对)

提前谢谢

编辑 从我的理解来看,事情就是这样。我想出于某种原因,我可能有更高的期望,但这在Js中是可以解释的,所以至少有一些一致性

对于创建包含新成员的新阵列,我能想到的最优雅的解决方案是

return _.map(array, (item) => _.assign({}, ...item, {isSelected: true}));   

.map
将创建一个新数组,但数组中的对象仍被引用

因此,当您在
object item
inside.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

信用证:克隆函数是从修改get通过引用传递给map函数的对象(而不是get映射的数组)复制而来的。
changedArray
initialArray
都包含相同的对象

var initialArray=[{name:'one'},{name:'two'},{name:'three'}];
var initialArray2=[{name:'one'},{name:'two'},{name:'three'}];
函数剂量测量(数组){
//香草的
返回数组.map(函数(项){
项目['isSelected']=true;
退货项目
});
}
函数doSomethingElse(数组){
返回数组.map(函数(项){
//返回一个新对象,不要更改初始对象
返回{name:item.name,isSelected:true};
});
}
var changedArray=剂量测量(初始阵列),
DifferentingObjectsInArray=doSomethingElse(初始数组2);
assert(initialArray!==changedArray,“两个数组都不同”);
assert(initialArray[0]!==changedArray[0],“两个数组引用不同的对象”);
assert(initialArray2[0]!==differentitobjectsInArray[0],“两个数组引用不同的对象”);
log('initialArray',initialArray);
console.log('initialArray2',initialArray2);
log('differentitobjectsinarray',differentitobjectsinarray)
使用ES6:

let newArray = [...oldArray].map(doStuff);

如果您只想求解OP的示例,那么可以将
对象扩展到从
Array.map()
返回的新对象中

var initialArray=[{name:'one'},{name:'two'},{name:'three'}];
函数剂量测量(数组){
//洛达斯
//返回{.map(数组,(项)=>{.assign(项,{isSelected:true}));
//香草的
返回数组.map(函数(项){
返回{
…项目,
是的
}
});
}
var changedArray=剂量测量(初始数组);
console.log('initialArray',initialArray);//initialArray[{name:'one'},{name:'two'},{name:'three'}] 
console.log('changedArray',changedArray);//changedArray[{name:'one',isSelected:true}, {name:'two',isSelected:true},{name:'twree',isSelected:true}]

console.log(initialArray==changedArray);//false
关于最后一行的注释:
console.log(initialArray…
。如果您必须在JavaScript中比较数组(或对象),这几乎不起作用。请看一看小提琴:我不能将其作为答案发布,因为它将脱离主题,但这里有一个很好的答案:您可以使用array.slice()不使用克隆函数,但是可以。或者使用任何选项(查看最适合您需要的性能),也可以通过使用
Object.assign({},propertyOrTheWholeObjectToBeCopied)来复制原始属性
。这仅适用于1级深度复制。虽然此代码可能会解决OP的问题,但最好包括关于您的代码如何解决OP问题的解释。这样,未来的访问者可以从您的帖子中学习,并将其应用于他们自己的代码。因此,这不是编码服务,而是知识资源。此外,高质量、完整的answ这些功能,以及所有帖子都是独立的要求,是SO作为一个平台的一些优势,使其区别于论坛。您可以编辑以添加其他信息和/或用源文档补充您的解释。
 var targetArray=JSON.parse(JSON.stringify(souceArray));