使用forEach、映射或筛选器克隆和操作嵌套对象,而不修改原始对象

Cloning and manipulating nested object using forEach, map, or filter without modifying original object

本文关键字:对象 嵌套 操作 原始 修改 映射 forEach 筛选 使用      更新时间:2023-09-26

我正在尝试使用.map、.filter来克隆和修改一个基于深度嵌套属性的大型嵌套JSON对象。使用下面的代码,原始datafiltered数据最终都会被修改,但我试图保持原始data不变。我希望做的是在给定id的最终filtered对象中清空深度嵌套的concerns数组,留下原始的data作为原始的完整数据集。

var data {...};
var dataFilter = function dataBuild(data) {
  var newData = data;
  newData.service_requests = newData.service_requests.map((request) => {
    request.concerns = request.concerns.filter((concern) => {
      return concern.building_id == 2
    });
    return request;
  });
    return newData;
};
var filtered = dataFilter(data);

这是我试图用里面的整个物体做的一个小提琴。http://jsbin.com/doyoqinoxo/edit?js,控制台

当你这样做时:

var newData = data;

你只是对同一个对象进行了第二次引用,所以:

newData.service_requests = ...

覆盖data.service_requests.中的值

您似乎希望newData数据的副本,而不是对同一对象的引用。这里有很多关于如何复制嵌套对象(所谓的深度复制)的帖子,例如,克隆对象的最有效方法是什么?,但请忽略已接受的答案,除非您使用的是jQuery。使用其他答案中的一个,比如这个。

JSIterator.map()创建具有相同元素数的新数组,或者不更改原始数组。如果数组中有对象复制相同的引用,则引用可能会出现问题,因此,当您对对象的属性进行任何更改时,它将更改包含相同引用的元素的原始值。

解决方案是复制对象,好吧,array.Splice()[...array](spread Operator)在这种情况下没有帮助,你可以使用Loadash之类的JavaScript实用程序库,或者只使用下面提到的代码:

const newList = JSON.parse(JSON.stringify(orinalArr))