当前位置:  开发笔记 > 编程语言 > 正文

Js Array.prototype.map()碰巧是可变的吗?

如何解决《JsArray.prototype.map()碰巧是可变的吗?》经验,为你挑选了1个好方法。

当最初的目的是创建一个新数组时,为什么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

首先我想了解为什么会这样?

第二个我喜欢理解如何在不改变原始数组的情况下映射数组?(即._cloneDeep每次map做错之前都做过)

提前致谢 !

编辑

好吧,据我所知,这就是事情的真实情况.我想我可能因某种原因有更高的期望,但在Js中可以解释,所以至少存在一定的一致性.

我能想到的用于创建具有新成员的新阵列的最优雅的解决方案是

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

Oxi.. 9

.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

Credit:从此帖子复制克隆功能



1> Oxi..:

.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

Credit:从此帖子复制克隆功能

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有