Lesson5:ES6簡易入門(裝飾器Decorator的用法)

類的修飾

許多面向對象的語言都有裝飾器(Decorator)函數,用來修改類的行為。目前,有一個提案將這項功能,引入了 ECMAScript。

@testable
class MyTestableClass {
  // ...
}

function testable(target) {
  target.isTestable = true;
}

MyTestableClass.isTestable // true

上面代碼中,@testable就是一個裝飾器。它修改了MyTestableClass這個類的行為,為它加上了靜態屬性isTestabletestable函數的參數targetMyTestableClass類本身。

基本上,裝飾器的行為就是下面這樣。

@decorator
class A {}

// 等同于

class A {}
A = decorator(A) || A;

也就是說,裝飾器是一個對類進行處理的函數。裝飾器函數的第一個參數,就是所要修飾的目標類。

如果覺得一個參數不夠用,可以在裝飾器外面再封裝一層函數。

function testable(isTestable) {
  return function(target) {
    target.isTestable = isTestable;
  }
}

@testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true

@testable(false)
class MyClass {}
MyClass.isTestable // false

上面代碼中,裝飾器testable可以接受參數,這就等于可以修改裝飾器的行為。

注意,裝飾器對類的行為的改變,是代碼編譯時發生的,而不是在運行時。這意味著,裝飾器能在編譯階段運行代碼。也就是說,裝飾器本質就是編譯時執行的函數。

前面的例子是為類添加一個靜態屬性,如果想添加實例屬性,可以通過目標類的prototype對象操作。

function testable(target) {
  target.prototype.isTestable = true;
}

@testable
class MyTestableClass {}

let obj = new MyTestableClass();
obj.isTestable // true

上面代碼中,裝飾器函數testable是在目標類的prototype對象上添加屬性,因此就可以在實例上調用。

方法的修飾

裝飾器不僅可以修飾類,還可以修飾類的屬性。

class Person {
  @readonly
  name() { return `${this.first} ${this.last}` }
}

上面代碼中,裝飾器readonly用來修飾“類”的name方法。

此時,裝飾器函數一共可以接受三個參數,第一個參數是所要修飾的目標對象,即類的實例(這不同于類的修飾,那種情況時target參數指的是類本身);第二個參數是所要修飾的屬性名,第三個參數是該屬性的描述對象。

function readonly(target, name, descriptor){
  // descriptor對象原來的值如下
  // {
  //   value: specifiedFunction,
  //   enumerable: false,
  //   configurable: true,
  //   writable: true
  // };
  descriptor.writable = false;
  return descriptor;
}

readonly(Person.prototype, 'name', descriptor);
// 類似于
Object.defineProperty(Person.prototype, 'name', descriptor);

上面代碼說明,裝飾器(readonly)會修改屬性的描述對象(descriptor),然后被修改的描述對象再用來定義屬性。

使用裝飾器的注意點

  • 修飾器只能用于類和類的方法,不能用于函數,因為存在函數提升
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 人生苦多,快來 Kotlin ,快速學習Kotlin! 什么是Kotlin? Kotlin 是種靜態類型編程...
    任半生囂狂閱讀 26,276評論 9 118
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,373評論 25 708
  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,167評論 6 13
  • 本文為阮一峰大神的《ECMAScript 6 入門》的個人版提純! babel babel負責將JS高級語法轉義,...
    Devildi已被占用閱讀 2,021評論 0 4
  • 我想寫信給他 托白云送去 告訴他 我這里今天回南天了 墻壁和樓梯都濕濕的 告訴他 我撿的鴨鴨青春期了 但囗欲期還沒...
    三月品閱讀 139評論 0 0