JS Array.prototype.map()碰巧是可变的吗? [英] Js Array.prototype.map() happens to be mutable?

查看:83
本文介绍了JS Array.prototype.map()碰巧是可变的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么map方法

Why would the map method mutate the original array when its initial purpose is to create a new array ?

我有一个对象数组,我将其传递给一个纯函数,该函数依次映射给定的数组并返回一个新的数组.然后,我注意到原始数组也发生了变化..我理解了Js中的Object通过引用传递的概念,但几乎所有人仍然无法理解为什么 map 的实现会导致原始数组发生变化,有点超出了IMO的目的.

I have an array of object which I pass to a pure function which in turn maps the given array and return a new one. Then I notice that the original array was also changed.. I understand the concept that Object in Js are passed by reference and all but still cant quite grab why would the implementation of map would mutate the original array, kinda beats the purpose 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

第一个想了解为什么会发生这种情况?

First Id like to understand why this happens ?

第二个ID想了解如何在不更改原始数组的情况下映射数组?(即,在 map 感觉不对之前每次执行 ._ cloneDeep )

Second Id like to understand how would one map an array without changing the original one ? (ie. doing ._cloneDeep each time before map feels wrong)

提前谢谢!

好吧,据我了解,这就是事实.我认为出于某些原因我可能有更高的期望,但是在Js中可以解释,因此至少在一定程度上具有一定的一致性.

Ok so from what I understand this is how things just are. I think I might have had higher expectation for some reason, but it is explainable in Js so at least there is some consistency in place.

用新成员创建新数组时,我能想到的最优雅的解决方案是

The most elegant solution I can think of for creating a new array with new members is

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

推荐答案

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

.map will create a new array, but the objects inside the array is still referenced.

因此,当您在.map函数内的 object项目中进行更改时,它引用了输入数组中的原始对象.

so when you make changes in the object item inside .map function, it is referencing the original object in the input array.

一种修复方法是在修改对象之前先克隆每个对象

one way to fix it is to clone the each object , before you modify it

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 : clone function is copied from this post

这篇关于JS Array.prototype.map()碰巧是可变的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆