我有一个超类,它是许多子类(Customer, Product, ProductCategory…)的父类(Entity)。

我想在Typescript中动态克隆一个包含不同子对象的对象。

例如:拥有不同产品的客户拥有一个ProductCategory

var cust:Customer  = new Customer ();

cust.name = "someName";
cust.products.push(new Product(someId1));
cust.products.push(new Product(someId2));

为了克隆对象的整个树,我在实体中创建了一个函数

public clone():any {
    var cloneObj = new this.constructor();
    for (var attribut in this) {
        if(typeof this[attribut] === "object"){
           cloneObj[attribut] = this.clone();
        } else {
           cloneObj[attribut] = this[attribut];
        }
    }
    return cloneObj;
}

当new被转译为javascript时,将引发以下错误:错误TS2351:不能对缺少调用或构造签名的表达式使用'new'。

虽然脚本工作,但我想摆脱转译错误


当前回答

对于可序列化的深度克隆,类型信息为,

export function clone<T>(a: T): T {
  return JSON.parse(JSON.stringify(a));
}

其他回答

最后我这样做了:

public clone(): any {
  const result = new (<any>this.constructor);

  // some deserialization code I hade in place already...
  // which deep copies all serialized properties of the
  // object graph
  // result.deserialize(this)

  // you could use any of the usggestions in the other answers to
  // copy over all the desired fields / properties

  return result;
}

因为:

var cloneObj = new (<any>this.constructor());

@Fenton给出了运行时错误。

Typescript版本:2.4.2

对于可序列化的深度克隆,类型信息为,

export function clone<T>(a: T): T {
  return JSON.parse(JSON.stringify(a));
}

TypeScript/JavaScript有自己的浅克隆操作符:

let shallowClone = { ...original };

你可以在扩展语法中使用解构赋值:

var obj = {id = 1, name = 'product1'};
var clonedObject = {...obj};

我的看法是:

Object.assign(…)只复制属性,我们丢失了原型和方法。

Object.create(…)不是为我复制属性,只是创建一个原型。

对我有用的是使用Object.create(…)创建一个原型,并使用Object.assign(…)将属性复制到它:

因此对于对象foo,像这样进行克隆:

Object.assign(Object.create(foo), foo)