【问题标题】:Typescript: Object.assign - shallow or deep copy for delete打字稿:Object.assign - 用于删除的浅拷贝或深拷贝
【发布时间】:2020-02-25 13:30:06
【问题描述】:

我有一个像data.edit.lstAnnotation.lstComments 这样结构的对象

...
lstAnnotation?: AnnotationInterface;
...
export interface AnnotationInterface {
  lstComments: CommentList;
}
export class CommentList {
  [key: string]: CommentEntity;
}
...

据我了解,Object.assign() 函数会进行浅拷贝。这意味着不会复制内容并保留引用。我有一个类似的功能

Object.keys(this.data.edit.lstAnnotation.lstComments).map((key: string) => {
      const newEntity = {...this.data.edit.lstAnnotation.lstComments[key]};
      delete newEntity.cur; // <<<<----------------- [1]
      if (newEntity.add && newEntity.add.trim().length === 0) {
        delete newEntity.add;  // <<<<-------------- [2]
      }
      return JSON.stringify(newEntity);
    }).join();

这是一个很好的字符串。据我了解,我创建了内容的shallow copy,然后删除(delete)属性。我的问题是,为什么delete 没有应用于原始列表(data.edit.lstAnnotation.lstComments)?

我仍然在data.edit.lstAnnotation.lstComments 条目中使用key cur,例如data.edit.lstAnnotation.lstComments['abc'].cur ==> object....

我对目前的情况很满意。但是,如果我从复制的对象中删除并且原始对象没有更新,我会说这是一个深层副本。那么,我的错误在哪里?

【问题讨论】:

  • 您的代码在任何地方都没有调用Object.assign...这是一个错误吗?如果您希望通过删除属性更改副本也应该更改原始文件,那么您认为与根本不制作副本应该有什么不同的行为尚不清楚。你打算如何让const copy = {...original}; 在行为上与const copy = original; 不同?
  • 我认为{...original}Object.assign{{},original} 相同,尽管我不太确定。尤其是因为后者有时间惩罚。
  • Object spread syntax 不完全等同于Object.assign,因为它是doesn't trigger setters,而Object.assign 是。

标签: typescript javascript-objects deep-copy


【解决方案1】:

下面是一些演示核心问题的示例代码:

const array = [1, 2, 3];
const original = {a: array, b: 4};
const copy = {};
Object.assign(copy, original);
delete copy.a;

会发生什么:

  • 创建了一个包含 1、2、3 的数组,array 持有对它的引用。
  • 创建一个对象时,属性a 持有对数组的引用,属性b 持有值4,original 持有对新对象的引用。
  • 创建的对象没有属性,copy 持有对它的引用。
  • Object.assignoriginal 引用的对象复制到 copy 引用的对象中。这是一个浅拷贝,所以copy.a 现在是对original.a 所引用的同一个数组的引用;没有复制数组。
  • 属于copy 所指对象的a 属性被删除,因此该对象不再具有名为a 的属性。 original 引用的对象仍然有自己的名为a 的属性,因为它是一个不同的对象。

stepping through the execution using the excellent Javascript Tutor tool 可以帮助你理解,它直观地显示了每行执行时程序状态会发生什么。

【讨论】:

  • 是的,我想我现在明白其中的区别了。多谢。尤其是 Javascript Tutor 真的很棒。
猜你喜欢
  • 1970-01-01
  • 2012-04-12
  • 2015-01-13
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-13
  • 2011-02-09
相关资源
最近更新 更多