Javascript 更新使用Object.assign创建的变量内的数组也会更新原始变量
我已经使用Object.assign创建了一个变量的副本,并且我能够在不影响原始对象的情况下更改对象副本中的数组。但是,如果我尝试更新复制对象上数组中的值,这也会影响原始对象,即对job和updatedJob都进行了更改 我有以下代码:Javascript 更新使用Object.assign创建的变量内的数组也会更新原始变量,javascript,arrays,typescript,Javascript,Arrays,Typescript,我已经使用Object.assign创建了一个变量的副本,并且我能够在不影响原始对象的情况下更改对象副本中的数组。但是,如果我尝试更新复制对象上数组中的值,这也会影响原始对象,即对job和updatedJob都进行了更改 我有以下代码: // Create copy of "job" object which has been passed through let updatedJob = Object.assign({}, job); // Remove images from
// Create copy of "job" object which has been passed through
let updatedJob = Object.assign({}, job);
// Remove images from updated job object
updatedJob.Images = null;
// Remove checklist images from updated job object
_.each(updatedJob.Checklists, function (checklist) { checklist.Image = null; });
如您所见,我已经创建了一个已传递的作业对象的副本
如果我随后将updateJob对象的Images数组更改为null,则这可以正常工作,并且不会影响原始作业对象,即原始作业对象仍然具有完整的图像
然而,在代码的最后一行中,我试图迭代updatedJob对象中的Checklists数组,并将每个对象的Image属性更改为null,但这样做也会更新原始job对象
当updatedJob对象应该是原始job对象的副本,因此我对其所做的任何更改都不会影响原始job对象时,这怎么可能呢?object.assign执行浅层复制:它将一个对象的所有键值对复制到另一个对象中,如下所示:
const from = { primitive: "string", complex: { } }, to = {};
// Object.assign(from, to) basically does
to.primitive = from.primitive; // primitives are copied
to.complex = from.complex; // complex values references get copied, not the value itself
但是,对象数组也是对象,因此在您的示例中,两个对象的检查列表属性都指向同一个数组
您可以使用.map创建新数组,并重新分配属性以指向新数组:
updatedJob.Checklists = updatedJob.Checklists.map(checklist => ({ ...checklist, Image: null }));
此处的引用同样适用于此处,将.Image设置为null将影响两个数组中引用的对象,因此我们也必须复制这些对象。object.assign进行浅复制:它将一个对象的所有键值对复制到另一个对象中,如下所示:
const from = { primitive: "string", complex: { } }, to = {};
// Object.assign(from, to) basically does
to.primitive = from.primitive; // primitives are copied
to.complex = from.complex; // complex values references get copied, not the value itself
但是,对象数组也是对象,因此在您的示例中,两个对象的检查列表属性都指向同一个数组
您可以使用.map创建新数组,并重新分配属性以指向新数组:
updatedJob.Checklists = updatedJob.Checklists.map(checklist => ({ ...checklist, Image: null }));
此处的引用同样适用于此处,将.Image设置为null将影响两个数组中引用的对象,因此我们也必须复制这些对象。如注释和其他答案中所述,您正在进行浅层复制。你的代码中的每一个都表明你在使用lodash吗 如果是,请使用deepClone方法,以便递归复制项目:
let updatedJob = _.cloneDeep(job)
除此之外,还有其他问题需要解决,以提供合适的解决方案。如评论和其他答案中所述,您正在做一个浅显的复制。你的代码中的每一个都表明你在使用lodash吗 如果是,请使用deepClone方法,以便递归复制项目:
let updatedJob = _.cloneDeep(job)
否则,还有其他问题需要解决,以提供合适的解决方案。您创建了一份job的副本,但没有创建job.checklist的副本。您需要创建深度副本,而不是浅层副本。您创建了作业的副本,但没有创建作业的副本。检查列表。你需要做一个深拷贝,而不是浅拷贝。感谢Jonas的解释,我选择Daniel的解决方案,因为我在我的项目中使用了lodash。感谢Jonas的解释,我选择Daniel的解决方案,因为我在我的项目中使用了lodash。