1. 程式人生 > 其它 >JS 裝飾器(Decorator)

JS 裝飾器(Decorator)

Decorator是 ES7 的一個新語法,目前仍處於第2階段提案中,正如其“裝飾器”的叫法所表達的,他通過新增@方法名可以對一些物件進行裝飾包裝然後返回一個被包裝過的物件,可以裝飾的物件包括:類,屬性,方法等。

在使用它之前需要引入babel模組transform-decorators-legacy編譯成 ES5 或 ES6。

1. 類的裝飾

當裝飾的物件是類時,我們操作的就是這個類本身,即裝飾器函式的第一個引數,就是所要裝飾的目標類。

@decorator
class A {}

// 等同於
class A {}
A = decorator(A) || A;

示例:新增一個日誌裝飾器

@log
class MyClass { }

function log(target) { // 這個 target 在這裡就是 MyClass 這個類
   target.prototype.logger = () => `${target.name} 被呼叫`
}

const test = new MyClass()
test.logger() // MyClass 被呼叫

由於裝飾器是表示式,我們也可以在裝飾器後面再添加個引數:

@log('hi')
class MyClass { }

function log(text) {
  return function(target) {
    target.prototype.logger 
= () => `${text},${target.name} 被呼叫` } } const test = new MyClass() test.logger() // hello,MyClass 被呼叫

2. 屬性或方法的裝飾

對於類屬性或方法的裝飾本質是操作其描述符,可以把此時的裝飾器理解成是Object.defineProperty(obj, prop, descriptor)的語法糖。

class C {
  @readonly(false)
  method() { console.log('cat') }
}

function readonly(value) {
  
return function (target, key, descriptor) { /** * 此處 target 為 C.prototype; * key 為 method; * 原 descriptor 為:{ value: f, enumarable: false, writable: true, configurable: true } */ descriptor.writable = value return descriptor } } const c = new C() c.method = () => console.log('dog') c.method() // cat