'Why does map mutate array of objects?

Why does map mutate array of objects?

var obj = {
  items: [{
    value: 1,
    selected: true
  }, {
    value: 2,
    selected: false
  }]
};

var items = obj.items.map(i => {
  if (i.value === 2) i.selected = true;
  return i;
});

console.log(obj);


Solution 1:[1]

When you map an array, it's not creating a copy of the object. It's just iterating over the array.

If you don't want to mutate the object, you have to create a copy of the object:

var items = obj.items.map(item => {
    let i = JSON.parse(JSON.stringify(item))
    if (i.value === 2) i.selected = true;
    return i;
});

Solution 2:[2]

If you want a quick solution for an unmutable version of .map over an array of objects you can use the spread operator:

myArrayOfObjects.map(({...obj}) => { });

Example:

const foo = [];

for(let i = 0; i < 5; i++) {
    foo.push({label: "foo"});
}

const bar = foo.map(({...val}) => {
    val.id = Math.random();
  return val;
});

console.log(foo);
console.log(bar);

Solution 3:[3]

.map() as Hammerbot explained, does not create a copy, it creates a new array which directly references your object, thus mutating your object.

If you don't want to mutate your object, you can use Object.assign() within your mapping which creates a copy of the object.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Hammerbot
Solution 2 Manu Schiller
Solution 3 Alex