【问题标题】:Override constructor with an class decorator?用类装饰器覆盖构造函数?
【发布时间】:2017-04-09 07:53:05
【问题描述】:

如何使用 ES7 类装饰器覆盖构造函数?

例如,我想要类似的东西:

@injectAttributes({ foo: 42 })
class Bar {
  constructor() {
    console.log(this.foo);
  }
}

injectAttributes 装饰器将在新实例创建之前将属性注入其中:

> bar = new Bar();
42
> bar.foo
42

显而易见的解决方案——使用不同的构造函数:

 function overrideConstructor(cls, attrs) {
   Object.assign(this, attrs);
   cls.call(this);
 }

不起作用,因为创建的对象将是新构造函数的实例,而不是原始类型:

 > bar = new overrideConstructor(Bar, {foo: 42})
 42
 > bar
 [overrideConstructor {}]
 > bar instanceof Bar
 false

【问题讨论】:

  • ES7 中没有装饰器。
  • “不起作用,因为创建的对象将是新构造函数的实例,而不是原始类型” 没有“原始类型”。 Bar 是装饰的结果。或者更确切地说,因为 JavaScript 中没有装饰器。

标签: javascript class decorator ecmascript-next


【解决方案1】:

BabelJS REPL 不支持装饰器,所以我使用该函数(并手动包装),但概念是相同的。

Here 是工作代码,下面的复制/粘贴:

function injectAttributes(cls, attrs) {
  const injected = function(...args) {
    Object.assign(this, attrs);
    return cls.apply(this, args);
  }
  injected.prototype = cls.prototype;
  return injected;
}


class BareBar {
  constructor() {
    console.log(this.foo);
  }
}
const Bar = injectAttributes(new BareBar, { foo: 5 })

const thing = new Bar();
console.log(thing instanceof Bar);

打印出来:

5
true

装饰器创建一个新的构造函数,在其中注入属性,然后复制原始原型,以便instanceof 工作。

【讨论】:

  • Uncaught TypeError: Class constructor BareBar cannot be invoked without 'new'
猜你喜欢
  • 2021-02-04
  • 1970-01-01
  • 1970-01-01
  • 2017-05-04
  • 2017-07-12
  • 2015-02-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-17
相关资源
最近更新 更多