深拷贝,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 lodash
或 npm install lodash
安装 lodash
由于我们将只使用 cloneDeep
函数,为了减少包,我们将只将该函数导入组件,而不是整个 lodash
库:
import * as cloneDeep from 'lodash/cloneDeep';
那个,我们将像这样使用它来深拷贝对象:
copiedList = cloneDeep(originalList);
现在将某些内容更改为嵌套在副本中的对象不会更改原始对象。
此解决方案将为您的生产 Angular 包增加 18 kb。
我对 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 lodash
或 npm install lodash
lodash
由于我们将只使用 cloneDeep
函数,为了减少包,我们将只将该函数导入组件,而不是整个 lodash
库:
import * as cloneDeep from 'lodash/cloneDeep';
那个,我们将像这样使用它来深拷贝对象:
copiedList = cloneDeep(originalList);
现在将某些内容更改为嵌套在副本中的对象不会更改原始对象。
此解决方案将为您的生产 Angular 包增加 18 kb。