JavaScript修飾器-讓程式碼更乾淨

cipchk發表於2019-02-16

一般在JavaScript中為了讓部分程式碼延遲執行,一想起的自然是 setTimeout,比如:

setTimeout(() => {
  // doing
}, 0);

這種程式碼或許你不知道寫過多少遍,但,我們在 setTimeout 中多數情況下會去呼叫另一個方法:

setTimeout(() => {
  this.fn();
}, 0);

你會發現,我們一直都在重複寫著 setTimeout,再套用一個匿名函式,最後才真正去編寫我們需要執行的方法。我越來越討厭這種寫法,老是寫著一些無關係要多餘的程式碼。

使用Angular的同學對 @Component 不陌生,裡面大量的使用這種ES7才會有的“修飾器”。

修飾器是一個函式,用於修改類行為。

那, 應該怎麼編寫一個更乾淨的 setTimeout,比如,我希望這樣來編寫我的timeout:

@timeout(1000)
fn() {
  // doing
}

this.fn();

對應的 timeout 修飾器程式碼:

// timeout.ts
export function timeout(milliseconds: number = 0) {
  return function(target, key, descriptor) {
    // value 值相當於上面示例中 `change` 方法。
    var orgMethod = descriptor.value;
    descriptor.value = function(...args) {
      setTimeout(() => {
        orgMethod.apply(this, args);
      }, milliseconds);
    };
    return descriptor;
  }
}

target:例項物件,即 IndexComponent 例項化物件。
key:方法名稱,即 _fn_。
descriptor:物件描述,同Object.getOwnPropertyDescriptor() 。

怎麼樣,這樣子寫的程式碼是不是更酷?

修飾器目前只能在ES7才會有,但一些在Typescript、Babel等轉碼器已經被支援,特別是Angular2應用中更是給予非常重要的地位。而且應用範圍可以非常廣,比如類、類方法和屬性。

結論

以上只是一個很簡單的修飾器示例,你可以根據需要生產一些有意思的修飾器,讓編寫的程式碼更優雅、更乾淨。完整示例

相關文章