我有一个带有一些函数的常见打字稿类。
当我做-
所选实例不拥有this.selected = Object.assign({} as AssignedTestType, newTestType);
中的函数。
如何使用object.assign创建“深层”副本?或任何替代方法?
答案 0 :(得分:8)
object.assign不复制函数
那是不真实的
Object.assign

所选实例不拥有AssignedTestType类型的函数。
现在这部分是真的。 FROM users
只会执行浅拷贝,只会枚举自己的道具
答案 1 :(得分:5)
如果您要复制的属性位于newTestType
的原型中,则不会复制它们,因为Object.assign
仅复制对象实例拥有属性。
替代方法是实例化您用于创建newTestType
的任何构造函数,并将结果实例分配给this.selected
,或者创建一个空对象并将其原型设置为newTestType
。在任何一种情况下,Object.assign
都是错误的工具。
答案 2 :(得分:0)
您在克隆对象上花费的精力取决于您想要做的事情。
第一个停靠点应为.clone 或 .cloneDeep。
此外,根据讨论,您可能正在讨论复制对原型上的函数的引用。在这种情况下,解决方案可能很简单:
class MyClass { foo() {} }
class MyOtherClass extends MyClass {}
console.log(new MyOtherClass().__proto__.foo); // foo from MyClass
如果你想看到一个hacky克隆函数,这是一个(未经测试的)开始(但它们可以根据你的要求变得非常复杂):
function clone(o) {
if(!isObject(o)) {
throw 'o must be a a non-function object';
}
return (function inner(a, b = {}) {
Object.keys(a).forEach(k => {
isObject(a[k])? b[k] = inner(a[k]) : b[k] = a[k];
});
return b;
}(o));
}
function isObject(o) {
return o !== null && typeof o === 'object'
}
var a = {
foo: 'foo',
bar: () => { console.log('bar'); },
bat: {
baz: () => { console.log('baz'); }
}
};
console.log(clone(a));
答案 3 :(得分:0)
快速克隆复杂对象:
代码
public static deepClone<T>(obj: any) {
if ( obj === null || obj === undefined) {
return obj;
} else if ( Array.isArray(obj)) {
const array: T[] = [];
obj.forEach( item => array.push( this.deepClone<typeof item>(item) ));
return array as T[];
} else {
const c = Object.assign({} as T, obj);
const fields: string[] = Object.getOwnPropertyNames(obj);
fields.forEach( f => {
const field = obj[f];
if ( typeof field === 'object' ) {
c[f] = this.deepClone<typeof field>(field);
}
});
return Object.assign({}, obj);
}
}
示例:
const x = {myProp: 'befor change value', c: {a: 1 , b: 2}, d: [1, 2, 3], func: () => {console.log('befor change function'); }};
const y = Object.assign(x);
const z = Utils.deepClone<any>(x);
console.log(x, y, z);
x.c.a = 12;
x.myProp = 'after change value';
x.func = () => console.log('after change function');
console.log(x, y, z);