【问题标题】:Why did mutation happen while filtering array of simple objects? [duplicate]为什么在过滤简单对象数组时会发生突变? [复制]
【发布时间】:2019-05-01 04:40:15
【问题描述】:

简单我的意思是数组中的对象只包含原语。根据规范:

... filter 为数组中的每个元素调用一次 callbackfn,按升序排列,并构造一个新数组,其中包含 callbackfn 返回 true 的所有值。 ...

那么为什么在这个例子中我基本上得到了指向初始数组而不是新数组的链接???

console.clear();

const array = [
  {id: 1, parent: 0},
  {id: 2, parent: 1},
  {id: 3, parent: 1},
  {id: 4, parent: 1}
];

const newArray = array.filter(el => el.id === 2 && {...el});
const newArray2 = array.map(el => ({...el}));
newArray[0].children = 3; // mutation of initial array
const newEl = {...array[2]};

console.log('Array: ', array);
console.log('newArray2: ', newArray2);
console.log('array[1] === newArray[0]: ', array[1] === newArray[0]); // WTF???
console.log('array[1] === newArray2[1]: ', array[1] === newArray2[1]);
console.log('newEl === array[2]: ', newEl === array[2]);

https://codepen.io/fanich37/pen/NEEqNp

【问题讨论】:

  • newArray[0].children = 3; 中,您正在改变一个object,它同时in 新数组和原始数组。看来您没有正确使用filter。过滤器行中的 {...el} 在这里没有任何作用。要观察arraynewArray 是单独的数组,您需要做的就是观察array === newArray 的值(这是错误的)。
  • 是的,filter 不适用于深度复制对象。

标签: javascript arrays


【解决方案1】:

Array.filter 不返回object,它只返回truefalse。当它返回true 时,原始数组的值被推送到新数组中。由于objects通过引用传递,即使它们在 2 个数组中被引用,它们也会继续共享引用。

因此,您需要在此处更改逻辑以确保引用已更改,即您添加一个指向某个不同引用的对象。

你可以像下面这样使用Array.map

const array = [{id: 1, parent: 0},{id: 2, parent: 1},{id: 3, parent: 1},{id: 4, parent: 1}];

const newArray = array.filter(el => el.id === 2).map(el => ({...el}));
console.log('array[1] === newArray[0]: ', array[1] === newArray[0]);

或者您可以使用Array.reduce,如下所示

const array = [{id: 1, parent: 0},{id: 2, parent: 1},{id: 3, parent: 1},{id: 4, parent: 1}];

const newArray = array.reduce((a,c) => {
  if(c.id===2) a.push({...c});
  return a;
}, []);
console.log('array[1] === newArray[0]: ', array[1] === newArray[0]);

【讨论】:

  • @AndreyAlexandrov - 很高兴为您提供帮助 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-04
相关资源
最近更新 更多