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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM