覆盖构造函数,带有课堂装饰器



我如何用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

babeljs repl不支持装饰器,因此我使用该功能(和手动包装),但概念是相同的。

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

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可以使用。

最新更新