Typescript 用数组传播深拷贝
Posted
技术标签:
【中文标题】Typescript 用数组传播深拷贝【英文标题】:Typescript spread deep copy with arrays 【发布时间】:2018-04-08 18:07:52 【问题描述】:我对打字稿中的展开运算符感到困惑
当我使用 .the 扩展运算符制作 object1 的副本时。
var object2 = ...object1, ;
即使 object1 包含其他对象,我也会得到一个包含所有 object1 项的深层副本的新 object2。
但是,如果 object1 中有一个数组,则会执行浅拷贝。在这种情况下,它似乎保持了 object1 和 object2 中的数组值之间的关系。
有没有办法使用扩展运算符深度复制数组?
【问题讨论】:
【参考方案1】:具有所有 object1 项的深层副本的新 object2
没有。传播总是一个浅拷贝。
示例
let orig = arr: [1,2,3]
let copy = ...orig
copy.arr.push(4)
console.log(orig.arr) // 1 2 3 4
更多
一些文档:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#object-spread-and-rest
【讨论】:
但是这个文档说“你也可以将一个对象传播到另一个对象中。一个常见的用例是简单地向一个对象添加一个属性而不改变原始对象:”所以如果我们不改变原始对象不是深拷贝吗? 这是不正确的,如果你有一个带有字段的对象,它是一个数组扩展运算符,则会复制对这个数组的引用,如果你在任何由扩展创建的对象中更改这个数组,它们都会改变。 Chrome 控制台:pastebin.com/JM5bgbvM @AdamMichalski 我添加了一个例子【参考方案2】:如果你需要深拷贝,怎么样:
var object2 = JSON.parse(JSON.stringify(object1));
【讨论】:
【参考方案3】:扩展运算符只复制对原始数组元素的引用。数组元素指向相同的内存位置。
对于深拷贝,我使用来自lodash 的 cloneDeep。
【讨论】:
【参考方案4】:这并没有直接回答问题,但我想告诉你我是如何做到的。在打字稿中,我通常为我的对象创建类,并为相同类型的对象创建构造函数。然后,您可以传递相同类型的对象,或者直接使用两个构造函数传递属性。
export class MyObject
myAttribute:string;
otherAttributes:Array<string>;
constructor();
constructor(myAttributeOrObj?:MyObject|string);
constructor(myAttributeOrObj?:any, otherAttributes:Array<string>)
if(myAttributeOrObj && myAttributeOrObj.myAttribute)
this.myAttribute = myAttributeOrObj.myAttribute;
this.createOtherAttributes(myAttributeOrObj.otherAttributes);
else
this.myAttribute=myAttributeOrObj;
this.createOtherAttributes(otherAttributes);
createOtherAttributes(arr)
this.otherAttributes = [];
for(var i = 0; i< arr.length; i++)
this.otherAttributes.push(arr[i]);
与使用现有库相比,此方法可能会产生开销,但使用此方法,您可以完全控制您的对象、类型,并且知道您制作的是深拷贝而不是浅拷贝。
更多关于构造函数重载的信息可以在这个问题Constructor overload in TypeScript中找到
【讨论】:
以上是关于Typescript 用数组传播深拷贝的主要内容,如果未能解决你的问题,请参考以下文章