Override constructor with an class decorator?

醉酒当歌 提交于 2019-12-23 12:23:06

问题


How can I override a constructor with an ES7 class decorator?

For example, I'd like to have something like:

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

Where the injectAttributes decorator will inject attributes into new instances before they are created:

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

The obvious solution – using a different constructor:

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

Does not work because the object created will be an instance of the new constructor, not the original type:

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

回答1:


The BabelJS REPL doesn't support decorators so I am using the function (and manually wrapping) but the concept is the same.

Here is the code working, and the copy/paste below:

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(BareBar, { foo: 5 })

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

This prints:

5
true

The decorator creates a new constructor, where attributes are injected, and then copies over the original prototype so that instanceof works.



来源:https://stackoverflow.com/questions/40796074/override-constructor-with-an-class-decorator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!