【问题标题】:Class Decorator in TypescriptTypescript 中的类装饰器
【发布时间】:2017-11-15 02:25:46
【问题描述】:

当我们希望替换构造函数时,我试图了解类装饰器在 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

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

newConstructor.prototype = originalConstructor.prototype;

我们为什么要这样做?

【问题讨论】:

  • 让我们从您的代码并没有真正做到您认为的那样做开始。它不起作用。将ctor 更改为constructor(public name: string, public age: number),然后尝试访问实例成员(nameage),您将获得undefined。检查这个问题的正确方法:stackoverflow.com/questions/39198811/…
  • 嗨,这段代码来自互联网,我不在乎它是否有效我只需要知道为什么我们需要这条线,因为我已经在更多示例中看​​到了它

标签: javascript typescript decorator


【解决方案1】:

类如:

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

在面向 ES5 时编译成函数:

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

正如您在我们使用函数定义类时所看到的那样。方法被添加到函数的原型中。

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

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;
}

您可以通过"Decorators & metadata reflection in TypeScript: From Novice to Expert (Part I)"了解更多信息

更新

请参阅https://github.com/remojansen/LearningTypeScript/tree/master/chapters/chapter_08 获取更新版本。

【讨论】:

  • 这与是否为ES5 无关。 ES6 也是如此
  • 抛出错误。答案的代码示例取自旧源(2015)。 TypeError: Cannot read property 'prototype' of undefined 参考原型分配步骤。我认为没有一种简单的方法可以复制原型。我希望能够在不改变对构造函数原型的原始引用的情况下清晰简洁地对其进行编码:(。
  • 这段代码已经好几个月了。更新版本请参考github.com/remojansen/LearningTypeScript/tree/master/chapters/…
猜你喜欢
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
  • 2022-08-15
  • 2020-08-29
  • 2018-06-30
  • 1970-01-01
  • 2019-07-23
  • 2018-06-08
相关资源
最近更新 更多