深拷贝,孩子仍然参考原始对象

问题描述 投票:0回答:2

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

enter image description here

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

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
2个回答
0
投票

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

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

或者一次串起整个this.periods

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

0
投票

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

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

lodashyarn add lodash安装npm install lodash

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

import * as cloneDeep from 'lodash/cloneDeep';

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

copiedList = cloneDeep(originalList);

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

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

© www.soinside.com 2019 - 2024. All rights reserved.