原文地址:https://www.jeremyjone.com/666/, 轉載請註明。
js中的裝飾器一直處於提案階段,所以要是用裝飾符@
,就需要通過babel進行解析。
安裝babel的插件
如果 babel < 7.x:
1、安裝npm install --save-dev babel-plugin-transform-decorators-legacy
2、在.babelrc
文件中添加:
{
"plugins": ["transform-decorators-legacy]
}
如果babel >= 7.x:
1、安裝npm install --save-dev @babel/plugin-proposal-decorators
2、在.babelrc
文件中添加:
{
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }],
]
}
注意順序:
如果插件中添加了transform-class-properties
,需要保證它在裝飾器插件的後面。
裝飾符的使用
要理解一個裝飾器,可以通過下面這個小例子:
class Circle {
draw() {
console.log("畫一個圓");
}
}
class Decorator {
constructor(circle) {
this.circle = circle;
}
draw() {
this.circle.draw();
this.setRedBorder(this.circle);
}
setRedBorder(circle) {
console.log("設置紅色邊框");
}
}
// 測試
let c = new Circle();
c.draw();
let d = new Decorator(c);
d.draw();
可以看到通過裝飾器方式,可以畫出一個帶紅色邊框的圓。
理解了裝飾器,裝飾符就大體可以理解了。
// 定義裝飾器函數,該方法可以接收裝飾符傳遞的參數
function log(type) {
// 這是裝飾符對應函數的標準接口函數。其中:target是作用的實例;name是作用的函數名;descriptor是一個標準裝飾器對象,其中value是對應作用的函數。
return function(target, name, descriptor) {
let oldValue = descriptor.value;
descriptor.value = function() {
// 打印日誌
console.log(`打印日誌:類型爲 - ${type}`);
// 執行原有方法
return oldValue.apply(this, arguments);
};
return descriptor;
}
}
// 使用方法
class A {
@log("text")
testFunc() {
console.log("函數方法");
}
}
let a = new A();
a.testFunc();
執行結果如下:
更多關於裝飾符@
的內容,可以看提案地址:https://github.com/tc39/proposal-decorators