深拷贝,children仍参考原文object

Deep copy, children still refer to original object

我对 object(TypeScript、Angular4、Ionic3)上的 deep copy/clone 有疑问,它还包含其他 object 的列表。每当我更改副本中的 child objects 时,原件也会受到更改的影响,反之亦然。我的 REST API 返回以下 JSON:

我有 2 种类型的 object 在这种情况下相关,还有更多但不需要更改,因此我不包括那些:

import { Declaration } from './declaration.entity';

export class Period{
    constructor(
        public number: number,
        public status: string,
        public year: number,
        public month: number,
        public sum: number,
        public orderNumber: string,
        public userId: string,
        public submitDate: Date,
        public comment: string,
        public declarations: Declaration[]
    ){}
}

import { FileCustom } from './file.entity';
import { Period } from './period.entity';

export class Declaration{
    constructor(
        public id: number,
        public status: string,
        public name: string,
        public description: string,
        public amount: number,
        public date: Date,
        public period: Period,
        public userId: string,
        public files: FileCustom[],
        public comment: string   
    ){}
}

我想更改句点内声明的字段。我有一个 object 称为句点(句点列表),我想克隆它。我需要一段时间不受影响。我查看了一些其他主题以及可能的解决方案并尝试了它们:

let cloned = this.periods.map(x => Object.assign({},x));

let cloned = this.periods.map(x => Object.assign([],x));

来自这个话题:

当我使用上述解决方案之一并更改副本中 句点 的评论字段时,原始文件保持不变。但是当我在句号内更改declaration的注释字段时,原始文件也被更改,这是我要防止的。我如何才能深入 copy/clone 我的时期列表,而没有任何 children 有 any 对原作的引用?

提前致谢。

如果对象原型不是问题并且对象不包含函数,您可以JSON.stringify()并将其解析回新对象

let cloned = this.periods.map(x => JSON.parse(JSON.stringify(x)));

或一次将整个 this.periods 字符串化

let cloned = JSON.parse(JSON.stringify(this.periods))

您可以使用 lodash 的 cloneDeep 函数来避免来回字符串化对象。

对于您的 Angular 项目,您可以这样做:

使用 yarn add lodashnpm install lodash

安装 lodash

由于我们将只使用 cloneDeep 函数,为了减少包,我们将只将该函数导入组件,而不是整个 lodash 库:

import * as cloneDeep from 'lodash/cloneDeep';

那个,我们将像这样使用它来深拷贝对象:

copiedList = cloneDeep(originalList);

现在将某些内容更改为嵌套在副本中的对象不会更改原始对象。

此解决方案将为您的生产 Angular 包增加 18 kb。