1

我有点在 JavaScript 中与继承作斗争。假设我有以下课程:

class Parent {
  constructor({ name, someOtherStuff } = {}) {
    this.name = name;
    this.someOtherStuff = someOtherStuff;
  }

  someMethod() {
    // ...
  }
}

我想创建一个装饰器,让我可以执行以下操作:

@parent({
  name: 'foo',
  someOtherStuff: 'bar'
})
class MyClass extends Component {
  myMethod() {
    // ...
  }
}

const instance = new MyClass();

// Those tests must pass
expect(instance.someMethod).toBeFunction();
expect(instance.name).toEqual('foo');
expect(instance.someOtherStuff).toEqual('bar');
expect(instance.myMethod).toBeFunction();
expect(instance instanceof Parent).toBe(true);
expect(instance instanceof MyClass).toBe(true);

有没有办法创建这样的装饰器?我尝试了多种解决方案,但没有一个真正满足所有测试。

const parent = (...args) => (Target) => {
  // Target corresponds to MyClass
  const parent = new Parent(...args);

  // ...
};

lodash 是允许的。

4

2 回答 2

3

为什么要使用装饰器?你可以扩展父类

class MyClass extends Parent {
    constructor() {
        super({name: 'foo', someOtherStuff: 'bar'});
    }
}
于 2016-08-03T14:49:58.910 回答
1

您可以使用装饰器创建一个继承的新类,应用一些 mixin,然后从那里开始。JS 类没有多重继承,所以你不能直接这样做,但你可以手动将两者结合起来,或者创建一个代理来做你想做的事。

我一直在通过返回如下类来为基于装饰器的 DI 库使用包装类:

static wrapClass(target, {hook = noop} = {}) {
  return class wrapper extends target {
    static get wrappedClass() {
      return target;
    }

    constructor(...args) {
      super(...Injector.fromParams(args).getDependencies(wrapper).concat(args));
    }
  }

}

装饰器实际上是在返回一个新的构造函数,并在原来的基础上关闭,但这对于大多数用途来说已经足够了。

于 2016-08-03T15:23:33.310 回答