admin管理员组

文章数量:1332395

I've noticed that deleting object properties when using Array.map() affects the original array, I assume since each iteration's item is still referencing the original array:

var objects = [{name: 'a', password: 'x'}, {name: 'b', password: 'x'}];

var clean = objects.map(user => {delete user.password; return user;});

console.log(JSON.stringify(objects));
> [{"name":"a"},{"name":"b"}]

Is there a way to use map or filter without it modifying the original? I can think to loop through each item and create a clone but curious if there's a simpler way.

I've noticed that deleting object properties when using Array.map() affects the original array, I assume since each iteration's item is still referencing the original array:

var objects = [{name: 'a', password: 'x'}, {name: 'b', password: 'x'}];

var clean = objects.map(user => {delete user.password; return user;});

console.log(JSON.stringify(objects));
> [{"name":"a"},{"name":"b"}]

Is there a way to use map or filter without it modifying the original? I can think to loop through each item and create a clone but curious if there's a simpler way.

Share Improve this question asked Aug 3, 2018 at 15:21 d-_-bd-_-b 23.2k43 gold badges171 silver badges284 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 4

You can reference everything except password with dereferencing. Then use map to build a new object with everything else. This is nice if you have other properties on the object other than name and want to include everything except password.

var objects = [{name: 'a', password: 'x'}, {name: 'b', password: 'x'}];

var clean = objects.map(({password, ...user}) => user);

console.log(objects);  // untouched

console.log(clean);    // no password

This is not a problem with map or filter, these methods always return a new array. This is a problem with objects always being passed by reference in Javascript.

Consider the following:

const a = { foo: 1 }
const b = { foo: 2 }

const arr1 = [ a, b ];

const arr2 = arr1.map(v => {
  v.foo = 0;
  return v;
});

console.log(arr1);
console.log(arr2);
console.log(JSON.stringify(arr1) === JSON.stringify(arr2)) // true

If you want to create a copy of each object in an array while doing a map you could use the spread operator:

const a = { foo: 1 }
const b = { foo: 2 }

const arr1 = [ a, b ];

const arr2 = arr1.map(v => {
  return {...v, foo: 0};
});

console.log(arr1);
console.log(arr2);
console.log(JSON.stringify(arr1) === JSON.stringify(arr2)) // false

It's worth noting that the spread operator is a shallow clone, this means that objects within objects will still be passed by reference.

const c = { foo: 3 }
const a = { foo: 1, biz: c }
const b = { foo: 2, biz: c }

const arr1 = [ a, b, c ];

const arr2 = arr1.map(v => {
  return {...v, foo: 0};
});

console.log(arr1);
console.log(arr2);
console.log(JSON.stringify(arr1) === JSON.stringify(arr2)) // false

You can map over all of the items and return only the name.

const objectsWithNames = objects.map(({name}) => ({name}));

The original array isn't being modified, but rather the items in the array (the objects) are. Since javascript objects are passed by reference, when you modify the objects in the new array, the references in the old array show the same modifications.

So, as you said, you can loop through each item and create a clone. Of course, you could perform a deep copy of the entire array too.

本文标签: Javascript Arraymap copy without changing originalStack Overflow