Typescript 中的类装饰器

Ris*_*skX 5 javascript decorator typescript

当我们希望替换构造函数时,我试图了解类装饰器在 Typescript 中是如何工作的。我看过这个演示:

const log = <T>(originalConstructor: new(...args: any[]) => T) => {
    function newConstructor(... args) {
        console.log("Arguments: ", args.join(", "));
        new originalConstructor(args);
    }
    newConstructor.prototype = originalConstructor.prototype;
    return newConstructor;
}

@log
class Pet {
    constructor(name: string, age: number) {}
}

new Pet("Azor", 12);
//Arguments: Azor, 12
Run Code Online (Sandbox Code Playgroud)

一切都明白了,但这一行:

newConstructor.prototype = originalConstructor.prototype;
Run Code Online (Sandbox Code Playgroud)

我们为什么要这样做?

Rem*_*sen 3

这些课程如:

class Pet {
    constructor(name: string, age: number) {}
    dosomething() {
        console.log("Something...");
    }
}
Run Code Online (Sandbox Code Playgroud)

当针对 ES5 时编译成函数:

var Pet = (function () {
    function Pet(name, age) {
    }
    Pet.prototype.dosomething = function () {
        console.log("Something...");
    };
    return Pet;
}());
Run Code Online (Sandbox Code Playgroud)

正如您所见,当我们使用函数来定义类时。这些方法被添加到函数的原型中。

这意味着如果您要创建一个新的构造函数(新函数),您需要从旧对象复制所有方法(原型):

function logClass(target: any) {

  // save a reference to the original constructor
  const original = target;

  // a utility function to generate instances of a class
  function construct(constructor: any, args: any[]) {
    const c: any = function () {
      return constructor.apply(this, args);
    };
    c.prototype = constructor.prototype;
    return new c();
  }

  // the new constructor behaviour
  const newConstructor: any = function (...args: any[]) {
    console.log("New: " + original.name);
    return construct(original, args);
  };

  // copy prototype so intanceof operator still works
  newConstructor.prototype = original.prototype;

  // return new constructor (will override original)
  return newConstructor;
}
Run Code Online (Sandbox Code Playgroud)

您可以在“TypeScript 中的装饰器和元数据反射:从新手到专家(第一部分)”中了解更多信息

更新

请参阅https://github.com/remojansen/LearningTypeScript/tree/master/chapters/chapter_08了解最新版本。