使用非遗留装饰器时如何装饰 JavaScript class 构造函数?
How to decorate a JavaScript class constructor when using non-legacy decorators?
我有以下 class:
@log
class Example {
constructor(name, age) {
console.log("Example constructor", name, age);
this.name = name;
this.age = age;
}
}
而这个 @log
装饰器在使用遗留装饰器时:
function log(Class) {
return class extends Class {
constructor(...args) {
console.log("log", args);
super(...args);
}
};
}
// .babelrc
// ...
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }],
// ...
]
// ...
以上设置运行良好,下面的代码:
const example = new Example("Graham", 34);
输出:
log (2) ["Graham", 34]
Example constructor Graham 34
现在,我怎样才能在使用非遗留装饰器时获得相同的结果,即:
// .babelrc
// ...
"plugins": [
[
"@babel/plugin-proposal-decorators",
{ "decoratorsBeforeExport": false }
],
// ...
]
// ...
如何实现 @log
以使其与传统装饰器的工作方式相同?
function log(...args) {
const [descriptor] = args;
const { kind, elements } = descriptor;
const newElements = elements.concat({
kind: "method",
placement: "prototype",
key: "constructor",
descriptor: {
value: (...args) => {
// I have tried this but it doesn't work...
console.log("log", args);
},
configurable: true,
writable: true,
enumerable: true,
},
});
return {
kind,
elements: newElements,
};
}
我试过上面的代码,但没有用。问题是我在使用非遗留装饰器时没有对目标的引用。您知道是否有办法实现与旧版相同的行为?
谢谢。
我找到了答案,感谢 BabelJS Slack channel 上的 loganfsmyth。
您必须 return 一个带有 属性 的对象 finisher
包裹 class,例如:
function log(...args) {
const [descriptor] = args;
const { kind, elements } = descriptor;
return {
kind,
elements,
finisher: (Class) => {
return class extends Class {
constructor(...args) {
console.log("log", args);
super(...args);
}
};
}
};
}
然后使用非遗留装饰器时的代码:
@log
class Example {
constructor(name, age) {
console.log("Example constructor", name, age);
this.name = name;
this.age = age;
}
}
const example = new Example("Graham", 34);
输出:
log (2) ["Graham", 34]
Example constructor Graham 34
与遗留装饰器一样。
很难找到答案,因为 @babel/plugin-proposal-decorators.
上没有记录非遗留装饰器的这个特性
我有以下 class:
@log
class Example {
constructor(name, age) {
console.log("Example constructor", name, age);
this.name = name;
this.age = age;
}
}
而这个 @log
装饰器在使用遗留装饰器时:
function log(Class) {
return class extends Class {
constructor(...args) {
console.log("log", args);
super(...args);
}
};
}
// .babelrc
// ...
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }],
// ...
]
// ...
以上设置运行良好,下面的代码:
const example = new Example("Graham", 34);
输出:
log (2) ["Graham", 34]
Example constructor Graham 34
现在,我怎样才能在使用非遗留装饰器时获得相同的结果,即:
// .babelrc
// ...
"plugins": [
[
"@babel/plugin-proposal-decorators",
{ "decoratorsBeforeExport": false }
],
// ...
]
// ...
如何实现 @log
以使其与传统装饰器的工作方式相同?
function log(...args) {
const [descriptor] = args;
const { kind, elements } = descriptor;
const newElements = elements.concat({
kind: "method",
placement: "prototype",
key: "constructor",
descriptor: {
value: (...args) => {
// I have tried this but it doesn't work...
console.log("log", args);
},
configurable: true,
writable: true,
enumerable: true,
},
});
return {
kind,
elements: newElements,
};
}
我试过上面的代码,但没有用。问题是我在使用非遗留装饰器时没有对目标的引用。您知道是否有办法实现与旧版相同的行为?
谢谢。
我找到了答案,感谢 BabelJS Slack channel 上的 loganfsmyth。
您必须 return 一个带有 属性 的对象 finisher
包裹 class,例如:
function log(...args) {
const [descriptor] = args;
const { kind, elements } = descriptor;
return {
kind,
elements,
finisher: (Class) => {
return class extends Class {
constructor(...args) {
console.log("log", args);
super(...args);
}
};
}
};
}
然后使用非遗留装饰器时的代码:
@log
class Example {
constructor(name, age) {
console.log("Example constructor", name, age);
this.name = name;
this.age = age;
}
}
const example = new Example("Graham", 34);
输出:
log (2) ["Graham", 34]
Example constructor Graham 34
与遗留装饰器一样。
很难找到答案,因为 @babel/plugin-proposal-decorators.
上没有记录非遗留装饰器的这个特性