一般在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應用中更是給予非常重要的地位。而且應用範圍可以非常廣,比如類、類方法和屬性。
結論
以上只是一個很簡單的修飾器示例,你可以根據需要生產一些有意思的修飾器,讓編寫的程式碼更優雅、更乾淨。完整示例。