es6中什么是装饰器
本教程操作環(huán)境:windows7系統(tǒng)、ECMAScript 6版、Dell G3電腦。
裝飾器模式(Decorator Pattern)允許向一個現(xiàn)有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬于結構型模式,它是作為現(xiàn)有的類的一個包裝。
這種模式創(chuàng)建了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能。
ES6 裝飾器
在 ES6 中,裝飾器(Decorator)是一種與類相關的語法,用來注釋或修改類和類方法。
裝飾器其實就是一個函數(shù),通常放在類和類方法的前面。
裝飾器對類的行為的改變,是代碼編譯時發(fā)生的,而不是在運行時;裝飾器的本質就是編譯時執(zhí)行的函數(shù)
裝飾器可以用來裝飾整個類
@decorateClass
class Example {
@decorateMethods
method(){}
}
登錄后復制
在上面的代碼中使用了兩個裝飾器,其中 @decorateClass() 裝飾器用在類本身,用于增加或修改類的功能;@decorateMethods() 裝飾器用在類的方法,用于注釋或修改類方法。
兩種類型裝飾器
裝飾器只能用于類和類的方法,下面我們分別看下兩種類型的裝飾器的使用
1、類裝飾器
類裝飾器用來裝飾整個類
類裝飾器的參數(shù)
target: 類本身,也相當于是 類的構造函數(shù):Class.prototype.constructor。
@decorateClass
class Example {
//...
}
function decorateClass(target) {
target.isTestClass = true
}
登錄后復制
如上面代碼中,裝飾器 @decorateClass 修改了 Example 整個類的行為,為 Example 類添加了靜態(tài)屬性 isTestClass。裝飾器就是一個函數(shù),decorateClass 函數(shù)中的參數(shù) target 就是 Example 類本身,也相當于是類的構造函數(shù) Example.prototype.constructor.
裝飾器傳參
上面實現(xiàn)的裝飾器在使用時是不能傳入?yún)?shù)的,如果想要在使用裝飾器是傳入?yún)?shù),可以在裝飾器外面再封裝一層函數(shù)
@decorateClass(true)
class Example {
//...
}
function decorateClass(isTestClass) {
return function(target) {
target.isTestClass = isTestClass
}
}
登錄后復制
上面代碼中實現(xiàn)的裝飾器在使用時可以傳遞參數(shù),這樣就可以根據(jù)不同的場景來修改裝飾器的行為。
實際開發(fā)中,React 與 Redux 庫結合使用時,常常需要寫成下面這樣。
class MyReactComponent extends React.Component {}
export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
登錄后復制
有了裝飾器,就可以改寫上面的代碼。
@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {}
登錄后復制
2、類方法裝飾器
類方法裝飾器用來裝飾類的方法
類方法裝飾器的參數(shù)
-
target:
-
裝飾器修飾的類方法是靜態(tài)方法:target 為類的構造函數(shù)
-
裝飾器修飾的類方法是實例方法:target 為類的原型對象
-
method:被修飾的類方法的名稱
-
descriptor:被修飾成員的屬性描述符
// descriptor對象原來的值如下
{
value: specifiedFunction,
enumerable: false,
configurable: true,
writable: true
};
登錄后復制
class Example {
@log
instanceMethod() { }
@log
static staticMethod() { }
}
function log(target, methodName, descriptor) {
const oldValue = descriptor.value;
descriptor.value = function() {
console.log(`Calling ${name} with`, arguments);
return oldValue.apply(this, arguments);
};
return descriptor;
}
登錄后復制
如上面代碼中,裝飾器 @log 分別裝飾了實例方法 instanceMethod 和 靜態(tài)方法 staticMethod。@log 裝飾器的作用是在執(zhí)行原始的操作之前,執(zhí)行 console.log 來輸出日志。
類方法裝飾器傳參
上面實現(xiàn)的裝飾器在使用時是不能傳入?yún)?shù)的,如果想要在使用裝飾器是傳入?yún)?shù),可以在裝飾器外面再封裝一層函數(shù)
class Example {
@log(1)
instanceMethod() { }
@log(2)
static staticMethod() { }
}
function log(id) {
return (target, methodName, descriptor) => {
const oldValue = descriptor.value;
descriptor.value = function() {
console.log(`Calling ${name} with`, arguments, `this id is ${id}`);
return oldValue.apply(this, arguments);
};
return descriptor;
}
}
登錄后復制
上面代碼中實現(xiàn)的裝飾器在使用時可以傳遞參數(shù),這樣就可以根據(jù)不同的場景來修改裝飾器的行為。
類裝飾器與類方法裝飾器的執(zhí)行順序
如果在一個類中,同時使用裝飾器修飾類和類的方法,那么裝飾器的執(zhí)行順序是:先執(zhí)行類方法的裝飾器,再執(zhí)行類裝飾器。
如果同一個類或同一個類方法有多個裝飾器,會像剝洋蔥一樣,先從外到內進入,然后由內到外執(zhí)行。
// 類裝飾器
function decoratorClass(id){
console.log('decoratorClass evaluated', id);
return (target) => {
// target 類的構造函數(shù)
console.log('target 類的構造函數(shù):',target)
console.log('decoratorClass executed', id);
}
}
// 方法裝飾器
function decoratorMethods(id){
console.log('decoratorMethods evaluated', id);
return (target, property, descriptor) => {
// target 代表
// process.nextTick((() => {
target.abc = 123
console.log('method target',target)
// }))
console.log('decoratorMethods executed', id);
}
}
@decoratorClass(1)
@decoratorClass(2)
class Example {
@decoratorMethods(1)
@decoratorMethods(2)
method(){}
}
/** 輸入日志 **/
// decoratorMethods evaluated 1
// decoratorMethods evaluated 2
// method target Example { abc: 123 }
// decoratorMethods executed 2
// method target Example { abc: 123 }
// decoratorMethods executed 1
// decoratorClass evaluated 1
// decoratorClass evaluated 2
// target 類的構造函數(shù): [Function: Example]
// decoratorClass executed 2
// target 類的構造函數(shù): [Function: Example]
// decoratorClass executed 1
登錄后復制
如上面代碼中,會先執(zhí)行類方法的裝飾器 @decoratorMethods(1) 和 @decoratorMethods(2),執(zhí)行完后再執(zhí)行類裝飾器 @decoratorClass(1) 和 @decoratorClass(2)
上面代碼中的類方法裝飾器中,外層裝飾器 @decoratorMethods(1) 先進入,但是內層裝飾器 @decoratorMethods(2) 先執(zhí)行。類裝飾器同理。
利用裝飾器實現(xiàn)AOP切面編程
function log(target, name, descriptor) {
var oldValue = descriptor.value;
descriptor.value = function () {
console.log(`Calling "${name}" with`, arguments);
return oldValue.apply(null, arguments);
}
return descriptor;
}
// 日志應用
class Maths {
@log
add(a, b) {
return a + b;
}
}
const math = new Maths();
// passed parameters should get logged now
math.add(2, 4);
登錄后復制
【相關推薦:javascript視頻教程、web前端】
以上就是es6中什么是裝飾器的詳細內容,更多請關注風君子博客其它相關文章!
總結
以上是生活随笔為你收集整理的es6中什么是装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: p标签是什么元素
- 下一篇: 新浪微博和SAP CRM Interac