当前位置: 首页 > 面试题库 >

typescript - cloning object

东郭远航
2023-03-14
问题内容

我有一个超类是父(Entity)对于很多子类(CustomerProductProductCategory…)

我正在寻找动态克隆在Typescript中包含不同子对象的对象。

例如:一个Customer具有不同特征的Product人具有一个ProductCategory

var cust:Customer  = new Customer ();

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

为了克隆整个对象树,我在其中创建了一个函数 Entity

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上升时,它被transpiled为JavaScript以下错误:error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.

尽管该脚本有效,但 我想摆脱已编译的错误


问题答案:

解决具体问题

您可以使用类型断言来告诉编译器您更了解:

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

克隆

请记住,有时最好编写自己的映射-而不是完全动态。但是,您可以使用一些“克隆”技巧来给您带来不同的效果。

我将在下面的所有示例中使用以下代码:

class Example {
  constructor(public type: string) {

  }
}

class Customer {
  constructor(public name: string, public example: Example) {

  }

  greet() {
    return 'Hello ' + this.name;
  }
}

var customer = new Customer('David', new Example('DavidType'));

选项1:点差

属性:
方法:否
深度复制:否

var clone = { ...customer };

alert(clone.name + ' ' + clone.example.type); // David DavidType
//alert(clone.greet()); // Not OK

clone.name = 'Steve';
clone.example.type = 'SteveType';

alert(customer.name + ' ' + customer.example.type); // David SteveType

选项2:Object.assign

属性:
方法:否
深度复制:否

var clone = Object.assign({}, customer);

alert(clone.name + ' ' + clone.example.type); // David DavidType
alert(clone.greet()); // Not OK, although compiler won't spot it

clone.name = 'Steve';
clone.example.type = 'SteveType';

alert(customer.name + ' ' + customer.example.type); // David SteveType

选项3:Object.create

属性: 继承
方法: 继承的
深复制: 浅的继承 (深的更改会影响原始副本和克隆副本)

var clone = Object.create(customer);

alert(clone.name + ' ' + clone.example.type); // David DavidType
alert(clone.greet()); // OK

customer.name = 'Misha';
customer.example = new Example("MishaType");

// clone sees changes to original 
alert(clone.name + ' ' + clone.example.type); // Misha MishaType

clone.name = 'Steve';
clone.example.type = 'SteveType';

// original sees changes to clone
alert(customer.name + ' ' + customer.example.type); // Misha SteveType

选项4:深层复制功能

属性:
方法:否
深度复制:

function deepCopy(obj) {
    var copy;

    // Handle the 3 simple types, and null or undefined
    if (null == obj || "object" != typeof obj) return obj;

    // Handle Date
    if (obj instanceof Date) {
        copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
    }

    // Handle Array
    if (obj instanceof Array) {
        copy = [];
        for (var i = 0, len = obj.length; i < len; i++) {
            copy[i] = deepCopy(obj[i]);
        }
        return copy;
    }

    // Handle Object
    if (obj instanceof Object) {
        copy = {};
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = deepCopy(obj[attr]);
        }
        return copy;
    }

    throw new Error("Unable to copy obj! Its type isn't supported.");
}

var clone = <Customer>deepCopy(customer);

alert(clone.name + ' ' + clone.example.type); // David DavidType
// alert(clone.greet()); // Not OK - not really a customer

clone.name = 'Steve';
clone.example.type = 'SteveType';

alert(customer.name + ' ' + customer.example.type); // David DavidType


 类似资料:
  • 像函数参数一样,类有时具有可选成员。 同样的语法可以用于class定义: nickName?: string; 在上面的示例中,的实例保证有一个name,并且可以可选地具有nickName。 修饰符 public:类的每个成员默认为,可以自由被访问。 private:类成员被标记为private时就不能在类的外部访问。 继承与多态 封装,继承和多态是面型对象的三大特性。 TypeScript的

  • 类型 接口 形状 装饰 类型 许多人没有意识到这一点,JavaScript中实际上有类型的,但他们只是“鸭子类型”,这大概意味着程序员不必去想它们。TypeScript中也存在JavaScript的类型: boolean (true/false) number整数,浮点数,和NaN []其他类型的数组,如number[]或boolean[] {} 对象字面量 undefined 没有设置 enum

  • 请直接使用 @megalo/cli 创建 typescript 项目,如果你想了解相关的webpack配置感兴趣,可以配置 megalo-cli-service inspect 命令查看, 或者可查看 @megalo/cli-plugin-typescript

  • 从v5开始,Sequelize 提供了自己的 TypeScript 定义. 请注意,仅支持 TS >= 3.1. 由于 Sequelize 严重依赖于运行时属性赋值,因此 TypeScript 在开箱即用时不会非常有用. 需要大量的手动类型声明才能使模型可用. 安装 为了避免非 TS 用户的安装膨胀,你必须手动安装以下键入包: @types/node (这是普遍需要的) @types/valida

  • TypeScript 是微软新推出的一种语言,基于 JavaScript,是 JavaScript 的超集,最终通过工具编译生成 JavaScript。 TypeScript 兼容JavaScript,可以载入 JavaScript 代码然后运行。TypeScript 与 JavaScript 相比,进步的地方包括:加入注释,让编译器理解所支持的对象和函数,编译器会移除注释,不会增加开销;增加一个

  • TypeScript 类 TypeScript 是面向对象的 JavaScript。 类描述了所创建的对象共同的属性和方法。 TypeScript 支持面向对象的所有特性,比如 类、接口等。 TypeScript 类定义方式如下: 定义类的关键字为 class,后面紧跟类名,类可以包含以下几个模块(类的数据成员): 字段 − 字段是类里面声明的变量。字段表示对象的有关数据。 构造函数 − 类实例化