修飾器其實就是一個普通的函數,用來修飾類以及類的方法。
好比:html
@test class DecoratorTest { } function test(target) { target.testable = true; }
target 參數就是它修飾的類
這就表示給DecoratorTest這個類加上了一個靜態屬性 testable,等價於:vue
class DecoratorTest { public static testable = true; }
若是你以爲一個參數不夠用, 能夠在外面再套一層函數用來傳遞參數
就像這樣 :git
@testParam(true) class DecoratorTest { } function testParam(boolean bool) { return function test(target) { target.testable = bool; } }
這樣就更靈活些了。
剛纔咱們是用修飾器給類加了一個靜態屬性, 同理加實例屬性只須要在類的原型上給它加個屬性就好了es6
@testParam(true) class DecoratorTest { } function testParam(boolean bool) { return function test(target) { target.prototype.testable = bool; } }
::: warning
修飾器對類行爲的改變發生在代碼編譯階段,而不是運行階段
:::github
修飾器不只能夠修飾類, 還能夠修飾類中的屬性和方法
修飾什麼就放在什麼前面,web
修飾類中屬性和方法時,修飾器函數接受三個參數ide
function readonly(target, name, descriptor) { descriptor.writable = false; return descriptor; }
target 是目標對象, name是修飾的屬性名, descriptor是該屬性的描述對象
descriptor 通常長這樣函數
{ value : specifiedFunction, enumerable: false, configurable: true, writable: true }
它定義了該屬性是否可枚舉, 是否可讀,是否可配置
上面的readonly修飾器修飾的屬性不可寫
相似於this
Object.defineProperty(target, name, { value : specifiedFunction, enumerable: false, configurable: true, writable: false })
修飾器在js中不能用來修飾函數, 由於js中函數在預編譯階段存在函數提高prototype
core-decorators.js
此模塊封裝了幾個經常使用的修飾器