[英]Class decorator with stage-2 proposal and Babel 7
I am playing with stage-2 decorators proposal and I have found some problems with class decorators.我正在玩第 2 阶段装饰器提案,我发现类装饰器存在一些问题。 In legacy decorator, the next example works because class decorators took as their only argument a target constructor, but with stage-2 proposal receives a object descriptor.
在遗留装饰器中,下一个示例有效,因为类装饰器将目标构造函数作为其唯一参数,但在第 2 阶段提议中接收对象描述符。
function log(Class) {
return (...args) => {
console.log(`Arguments: ${args}`);
return new Class(...args);
};
}
@log
class Bar {
constructor(name, age) { }
}
I have read the tc39 proposal-decorators and built-in decorators,but it did not help me so much.我已经阅读了 tc39 提案装饰器和内置装饰器,但它对我没有多大帮助。 How can I make this example works with the new proposal decorator?
我怎样才能让这个例子与新的提案装饰器一起工作? is it possible to use built-in decorators with babel?
是否可以在 babel 中使用内置装饰器?
To try some stuff, I developed my own basic wrap decorator, it works as expected for methods, and I want to extend its functionality to class.为了尝试一些东西,我开发了自己的基本包装装饰器,它按预期方法工作,并且我想将其功能扩展到类。
const wrap = f => {
return wrapped => {
const { kind } = wrapped;
if (kind === 'class') {
return f(wrapped);
}
const { descriptor } = wrapped;
const original = descriptor.value;
descriptor.value = f(original);
return { ...wrapped, descriptor };
};
};
export default wrap;
With this basic decorator, I can create for example this logger method decorator that works.使用这个基本的装饰器,我可以创建例如这个有效的记录器方法装饰器。
import wrap from './wrap';
const loggerFunction = f => {
const name = f.name;
return function test(...args) {
console.log(`starting ${name} with arguments ${args.join(', ')}`);
return f.call(this, ...args);
};
};
export default wrap(loggerFunction);
And I can use it by this way:我可以通过这种方式使用它:
class Foo {
@logger
method(argument) {
return argument;
}
}
Your question is a bit old, but I think it is still actual so here is my answer:你的问题有点老了,但我认为它仍然是实际的,所以这是我的答案:
TLDR: Use a finisher
property to wrap your class when using non-legacy stage 2 decorators. TLDR:使用一个
finisher
财产使用非传统的阶段2个装饰时,包裹类。
The stage 2 API is not thoroughly documented and some things and use cases are missing.第 2 阶段的 API 没有完全记录,并且缺少一些东西和用例。
In order to achieve what you want, define a special finisher
property on the object you are returning in your decorator.为了实现您想要的效果,请在装饰器中返回的对象上定义一个特殊的
finisher
属性。
Therefore, this legacy
stage-1 decorator code:因此,这个
legacy
stage-1 装饰器代码:
function log(Class) {
return (...args) => {
console.log(`Arguments: ${args}`);
return new Class(...args);
};
}
@log
class Bar {
constructor(name, age) { }
}
Will be equivalent to this non-legacy
stage-2 decorator code:将等效于这个
non-legacy
第 2 阶段装饰器代码:
function log(descriptor) {
return {
...descriptor,
finisher: (Class) => (...args) => {
console.log(`Arguments: ${args}`);
return new Class(...args);
},
};
}
@log
class Bar {
constructor(name, age) {}
}
You can apply the same principle to your wrap
function.您可以将相同的原则应用于
wrap
功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.