我有一个超类,它是许多子类(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'。

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


当前回答

jQuery怎么样?!下面是深度克隆:

var clone = $.extend(true, {}, sourceObject);

其他回答

这是我的混搭!这里有一个StackBlitz的链接。它目前仅限于复制简单的类型和对象类型,但我认为可以很容易地修改。

   let deepClone = <T>(source: T): { [k: string]: any } => {
      let results: { [k: string]: any } = {};
      for (let P in source) {
        if (typeof source[P] === 'object') {
          results[P] = deepClone(source[P]);
        } else {
          results[P] = source[P];
        }
      }
      return results;
    };

添加“lodash。Clonedeep ": "^4.5.0"到你的package.json。然后像这样使用:

import * as _ from 'lodash';

...

const copy = _.cloneDeep(original)

如果你已经有了目标对象,所以你不想重新创建它(就像更新一个数组一样),你必须复制属性。 如果这样做:

Object.keys(source).forEach((key) => {
    copy[key] = source[key]
})

赞美是应得的。(请看标题“版本2”)

如果还想复制方法,而不仅仅是复制数据,请遵循此方法

let copy = new BaseLayer() ;
Object.assign(copy, origin);
copy.x = 8 ; //will not affect the origin object

只需将BaseLayer更改为类的名称。

我在克隆时使用以下方法。它处理我需要的几乎所有东西,甚至将函数复制到新创建的对象。

  public static clone<T>(value: any) : T {
    var o: any = <any>JSON.parse(JSON.stringify(value));
    var functions = (<String[]>Object.getOwnPropertyNames(Object.getPrototypeOf(value))).filter(a => a != 'constructor');
    for (var i = 0; i < functions.length; i++) {
      var name = functions[i].toString();
      o[name] = value[name];
    }
    return <T>o;
  }