溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

es6修飾器的作用是什么

發(fā)布時間:2023-02-02 09:22:17 來源:億速云 閱讀:140 作者:iii 欄目:web開發(fā)

這篇文章主要講解了“es6修飾器的作用是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“es6修飾器的作用是什么”吧!

在es6中,修飾器用來注釋或修改類和類的方法,依賴于ES5的“Object.defineProperty”方法,寫法為“@函數(shù)名”;修飾器其實就是一個函數(shù),通常放在類和類方法的前面。修飾器可以注入到類、方法、屬性參數(shù)上來擴展類、屬性、方法、參數(shù)的功能。

修飾器模式(Decorator Pattern)允許向一個現(xiàn)有的對象添加新的功能,同時又不改變其結(jié)構(gòu)。這種類型的設(shè)計模式屬于結(jié)構(gòu)型模式,它是作為現(xiàn)有的類的一個包裝。

這種模式創(chuàng)建了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能。

ES6 裝飾器(修飾器)

在 ES6 中,裝飾器(Decorator)是一種與類相關(guān)的語法,用來注釋或修改類和類方法。

裝飾器其實就是一個函數(shù),通常放在類和類方法的前面。

@decorateClass
class Example {
   @decorateMethods
   method(){}
}

在上面的代碼中使用了兩個裝飾器,其中 @decorateClass() 裝飾器用在類本身,用于增加或修改類的功能;@decorateMethods() 裝飾器用在類的方法,用于注釋或修改類方法。

兩種類型裝飾器(修飾器)

裝飾器只能用于類和類的方法,不能用于函數(shù),因為存在函數(shù)提升。

裝飾器只能用于類和類的方法,下面我們分別看下兩種類型的裝飾器的使用

類裝飾器

類裝飾器用來裝飾整個類

類裝飾器的參數(shù)

target: 類本身,也相當(dāng)于是 類的構(gòu)造函數(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 類本身,也相當(dāng)于是類的構(gòu)造函數(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 庫結(jié)合使用時,常常需要寫成下面這樣。

class MyReactComponent extends React.Component {}
export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);

有了裝飾器,就可以改寫上面的代碼。

@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {}

類方法裝飾器

類方法裝飾器用來裝飾類的方法

類方法裝飾器的參數(shù)
  • target:

  • 裝飾器修飾的類方法是靜態(tài)方法:target 為類的構(gòu)造函數(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í)行類裝飾器。

如果同一個類或同一個類方法有多個裝飾器,會像剝洋蔥一樣,先從外到內(nèi)進入,然后由內(nèi)到外執(zhí)行。

// 類裝飾器
function decoratorClass(id){
   console.log('decoratorClass evaluated', id);

   return (target) => {
       // target 類的構(gòu)造函數(shù)
       console.log('target 類的構(gòu)造函數(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 類的構(gòu)造函數(shù): [Function: Example]
// decoratorClass executed 2
// target 類的構(gòu)造函數(shù): [Function: Example]
// decoratorClass executed 1

如上面代碼中,會先執(zhí)行類方法的裝飾器 @decoratorMethods(1) 和 @decoratorMethods(2),執(zhí)行完后再執(zhí)行類裝飾器 @decoratorClass(1) 和 @decoratorClass(2)

上面代碼中的類方法裝飾器中,外層裝飾器 @decoratorMethods(1) 先進入,但是內(nèi)層裝飾器 @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;
}

// 日志應(yīng)用
class Maths {
    @log
    add(a, b) {
        return a + b;
    }
}
const math = new Maths();
// passed parameters should get logged now
math.add(2, 4);

感謝各位的閱讀,以上就是“es6修飾器的作用是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對es6修飾器的作用是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

es6
AI