打字稿:Object.assign - 用于删除的浅拷贝或深拷贝
Typescript: Object.assign - shallow or deep copy for delete
我有一个结构类似于 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....
我对目前的情况很满意。但是如果我从复制的对象中删除并且原始对象没有更新,我会说这是一个深拷贝。那么,我的错误在哪里?
下面是一些演示核心问题的示例代码:
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.assign
对 original
引用的对象进行浅拷贝,将其复制到 copy
引用的对象中。这是一个浅拷贝,所以 copy.a
现在是对 original.a
所引用的同一个数组的引用;没有创建数组的副本。
- 属于
copy
引用的对象的 a
属性 被删除,因此该对象不再具有名为 a
的 属性。 original
引用的对象仍然有自己的 属性 命名为 a
,因为它是一个不同的对象。
通过stepping through the execution using the excellent Javascript Tutor tool可以帮助您理解,它直观地显示了每行执行时程序状态发生了什么。
我有一个结构类似于 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....
我对目前的情况很满意。但是如果我从复制的对象中删除并且原始对象没有更新,我会说这是一个深拷贝。那么,我的错误在哪里?
下面是一些演示核心问题的示例代码:
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.assign
对original
引用的对象进行浅拷贝,将其复制到copy
引用的对象中。这是一个浅拷贝,所以copy.a
现在是对original.a
所引用的同一个数组的引用;没有创建数组的副本。- 属于
copy
引用的对象的a
属性 被删除,因此该对象不再具有名为a
的 属性。original
引用的对象仍然有自己的 属性 命名为a
,因为它是一个不同的对象。
通过stepping through the execution using the excellent Javascript Tutor tool可以帮助您理解,它直观地显示了每行执行时程序状态发生了什么。