ES6裡的修飾器Decorator

2022-01-21 06:22:38 字數 4364 閱讀 5849

修飾器(decorator)是乙個函式,用來修改類的行為。

es6 引入了這項功能,目前 babel 轉碼器已經支援decorator

首先,安裝babel-corebabel-plugin-transform-decorators。由於後者包括在babel-preset-stage-0之中,所以改為安裝babel-preset-stage-0亦可

$ npm install babel-core babel-plugin-transform-decorators

然後,設定配置檔案.babelrc

這時,babel就可以對decorator轉碼了

指令碼中開啟的命令如下

babel.transform("

code

", )

下面**中,@testable就是乙個修飾器。它修改了mytestableclass這個類的行為,為它加上了靜態屬性istestable

@testable

class

mytestableclass

function testable(target)

mytestableclass.istestable

//true

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

@decorator

class

a {}

//等同於

class

a {}

a = decorator(a) || a;

修飾器對類的行為的改變,是**編譯時發生的,而不是在執行時。這意味著,修飾器能在編譯階段執行**,也就是說,修飾器本質就是編譯時執行的函式

1、引數

修飾器函式的第乙個引數,是所要修飾的目標類

function testable(target)

如果覺得乙個引數不夠用,可以在修飾器外面再封裝一層函式

function testable(istestable) 

}@testable(

true

)class

mytestableclass {}

mytestableclass.istestable

//true

@testable(

false

)class

myclass {}

myclass.istestable

//false

上面**中,修飾器testable可以接受引數,這就等於可以修改修飾器的行為

前面的例子是為類新增乙個靜態屬性,如果想新增例項屬性,可以通過目標類的prototype物件操作

function testable(target) 

@testable

class

mytestableclass {}

let obj = new

mytestableclass();

obj.istestable

//true

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

class

person $` }

}

上面**中,修飾器readonly用來修飾「類」的name方法

1、引數

此時,修飾器函式一共可以接受三個引數,第乙個引數是所要修飾的目標物件,第二個引數是所要修飾的屬性名,第三個引數是該屬性的描述物件

function readonly

(target, name, descriptor);

descriptor.writable = false;

return

descriptor;

}readonly(person.prototype, '

name

', descriptor);

//類似於

object.defineproperty(person.prototype, '

name

', descriptor);

上面**說明,修飾器(readonly)會修改屬性的描述物件(descriptor),然後被修改的描述物件再用來定義屬性。

下面是另乙個例子,修改屬性描述物件的enumerable屬性,使得該屬性不可遍歷

class

person

}function nonenumerable(target, name, descriptor)

2、日誌應用

下面的@log修飾器,可以起到輸出日誌的作用

class

math

}function log(target, name, descriptor)

"with`, arguments);

, arguments);

};return

descriptor;

}const math = new

math();

//passed parameters should get logged now

math.add(2, 4);

上面**中,@log修飾器的作用就是在執行原始的操作之前,執行一次console.log,從而達到輸出日誌的目的。

修飾器有注釋的作用

@testable

class

person $` }

}

從上面**中,我們一眼就能看出,person類是可測試的,而name方法是唯讀和不可列舉的

3、執行順序

如果同乙個方法有多個修飾器,會像剝洋蔥一樣,先從外到內進入,然後由內向外執行

function dec(id)

class

example }//

evaluated 1

//evaluated 2

//executed 2

//executed 1

上面**中,外層修飾器@dec(1)先進入,但是內層修飾器@dec(2)先執行

除了注釋,修飾器還能用來型別檢查。所以,對於類來說,這項功能相當有用。從長期來看,它將是js**靜態分析的重要工具

修飾器只能用於類和類的方法,不能用於函式,因為存在函式提公升

var counter = 0

;var add =function () ;

@add

function foo()

上面的**,意圖是執行後counter等於1,但是實際上結果是counter等於0。因為函式提公升,使得實際執行的**是下面這樣

@add

function foo()

varcounter;

varadd;

counter = 0

;add =function () ;

下面是另乙個例子

var readonly = require("

some-decorator");

@readonly

function foo()

上面**也有問題,因為實際執行是下面這樣

var

readonly;

@readonly

function foo()

readonly = require("

some-decorator

");

總之,由於存在函式提公升,使得修飾器不能用於函式。類是不會提公升的,所以就沒有這方面的問題。

另一方面,如果一定要修飾函式,可以採用高階函式的形式直接執行

function dosomething(name) 

return

function()

}

ES6裡的修飾器Decorator

修飾器 decorator 是乙個函式,用來修改類的行為。es6 引入了這項功能,目前 babel 轉碼器已經支援decorator 首先,安裝babel core和babel plugin transform decorators。由於後者包括在babel preset stage 0之中,所以改...

es6 使用修飾器實現Mixin模式

在修飾器的基礎上,可以實現mixin模式。所謂mixin模式,就是物件繼承的一種替代方案,中文譯為 混入 mix in 意為在乙個物件之中混入另外乙個物件的方法。請看下面的例子。const foo class myclass object assign myclass prototype foo l...

ES6的 迭代器

1,iterator 迭代器是es6提出的一種新的遍歷機制,目的是讓各種資料結構可方便地被訪問。可迭代物件由symbol.iterator實現,用symbol.iterator作為物件的屬性,鍵symbol.iterator的值是個函式,函式的執行返回乙個陣列的迭代器,可見 迭代器物件與symbol...