object.assign不复制函数

时间:2016-12-21 21:43:05

标签: javascript typescript ecmascript-6

我有一个带有一些函数的常见打字稿类。

当我做-

所选实例不拥有this.selected = Object.assign({} as AssignedTestType, newTestType);中的函数

如何使用object.assign创建“深层”副本?或任何替代方法?

4 个答案:

答案 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);