【问题标题】:Deep copy, children still refer to original object深拷贝,children 仍然引用原始对象
【发布时间】:2018-01-09 15:34:37
【问题描述】:

我在一个对象(TypeScript、Angular4、Ionic3)上存在深度复制/克隆问题,该对象还包含其他对象的列表。每当我更改副本中的子对象时,原始对象也会受到更改的影响,反之亦然。我的 REST API 给了我以下 JSON:

在这种情况下,我有两种相关的对象,还有更多但不需要更改,因此我不包括那些:

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   
    ){}
}

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

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

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

来自这个话题:

Deep copy an array in Angular 2 + TypeScript

当我使用上述解决方案之一并更改副本中 句号 的注释字段时,原始文件保持不变。但是当我在句号内更改声明的注释字段时,原始文件也被更改,这是我想要防止的。如何在没有任何子代任何对原始版本的引用的情况下深度复制/克隆我的期间列表?

提前致谢。

【问题讨论】:

标签: javascript angular typescript clone deep-copy


【解决方案1】:

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

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

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

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

【讨论】:

  • 谢谢,我使用了您的第一个解决方案,这对我有用。我将此答案标记为解决方案,但是,我仍然不完全理解。我将通读标记为重复的主题(Patrick 和 toskv)以了解这一点。
【解决方案2】:

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

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

使用yarn add lodashnpm install lodash 安装lodash

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

import * as cloneDeep from 'lodash/cloneDeep';

那,我们将像这样使用它来深度复制对象:

copiedList = cloneDeep(originalList);

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

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

【讨论】:

    猜你喜欢
    • 2017-08-30
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 2012-06-19
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多