我注意到使用Array.map()
时删除对象属性会影响原始数组,我认为由于每次迭代的项目仍在引用原始数组:
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"}]
是否可以使用map
或filter
而不修改原始文件?我可以考虑遍历每个项目并创建一个克隆,但很好奇是否有更简单的方法。
答案 0 :(得分:4)
您可以通过引用取消引用password
以外的所有内容。然后使用map与其他所有内容一起构建新对象。如果您在对象上具有name
以外的其他属性,并且想要包含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
答案 1 :(得分:3)
map
或filter
都不是问题,这些方法总是返回一个新数组。这是对象始终通过Javascript引用传递的问题。
请考虑以下内容:
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
如果要在制作地图时在数组中创建每个对象的副本,则可以使用散布运算符:
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
值得注意的是,散布运算符是一个浅表克隆,这意味着对象内的对象仍将通过引用传递。
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
答案 2 :(得分:1)
您可以映射所有项目并仅返回名称。
const objectsWithNames = objects.map(({name}) => ({name}));
答案 3 :(得分:0)
原始数组没有被修改,而是数组中的项目(对象)被修改了。由于javascript对象是通过引用传递的,因此当您修改新数组中的对象时,旧数组中的引用会显示相同的修改。
因此,正如您所说,您可以遍历每个项目并创建一个克隆。当然,您也可以对整个数组进行深层复制。