真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

es6中裝飾器怎么實(shí)現(xiàn)

這篇文章主要介紹“es6中裝飾器怎么實(shí)現(xiàn)”,在日常操作中,相信很多人在es6中裝飾器怎么實(shí)現(xiàn)問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”es6中裝飾器怎么實(shí)現(xiàn)”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

創(chuàng)新互聯(lián)建站專(zhuān)注于鹽池網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供鹽池營(yíng)銷(xiāo)型網(wǎng)站建設(shè),鹽池網(wǎng)站制作、鹽池網(wǎng)頁(yè)設(shè)計(jì)、鹽池網(wǎng)站官網(wǎng)定制、微信平臺(tái)小程序開(kāi)發(fā)服務(wù),打造鹽池網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供鹽池網(wǎng)站排名全網(wǎng)營(yíng)銷(xiāo)落地服務(wù)。

在es6中,裝飾器(Decorator)是一種與類(lèi)(class)相關(guān)的語(yǔ)法,用來(lái)注釋或修改類(lèi)和類(lèi)方法;裝飾器其實(shí)就是一個(gè)編譯時(shí)執(zhí)行的函數(shù),語(yǔ)法“@函數(shù)名”,通常放在類(lèi)和類(lèi)方法的定義前面。裝飾器有兩種:類(lèi)裝飾器和類(lèi)方法裝飾器。

本教程操作環(huán)境:windows7系統(tǒng)、ECMAScript 6版、Dell G3電腦。

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

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

ES6 裝飾器

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

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

裝飾器對(duì)類(lèi)的行為的改變,是代碼編譯時(shí)發(fā)生的,而不是在運(yùn)行時(shí);裝飾器的本質(zhì)就是編譯時(shí)執(zhí)行的函數(shù)

裝飾器可以用來(lái)裝飾整個(gè)類(lèi)

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

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

兩種類(lèi)型裝飾器

裝飾器只能用于類(lèi)和類(lèi)的方法,不能用于函數(shù),因?yàn)榇嬖诤瘮?shù)提升。

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

1、類(lèi)裝飾器

類(lèi)裝飾器用來(lái)裝飾整個(gè)類(lèi)

類(lèi)裝飾器的參數(shù)

target: 類(lèi)本身,也相當(dāng)于是 類(lèi)的構(gòu)造函數(shù):Class.prototype.constructor。

@decorateClass
class Example {
    //...
}

function decorateClass(target) {
    target.isTestClass = true
}

如上面代碼中,裝飾器 @decorateClass 修改了 Example 整個(gè)類(lèi)的行為,為 Example 類(lèi)添加了靜態(tài)屬性 isTestClass。裝飾器就是一個(gè)函數(shù),decorateClass 函數(shù)中的參數(shù) target 就是 Example 類(lèi)本身,也相當(dāng)于是類(lèi)的構(gòu)造函數(shù) Example.prototype.constructor.

裝飾器傳參

上面實(shí)現(xiàn)的裝飾器在使用時(shí)是不能傳入?yún)?shù)的,如果想要在使用裝飾器是傳入?yún)?shù),可以在裝飾器外面再封裝一層函數(shù)

@decorateClass(true)
class Example {
    //...
}

function decorateClass(isTestClass) {
    return function(target) {
  target.isTestClass = isTestClass
  }
}

上面代碼中實(shí)現(xiàn)的裝飾器在使用時(shí)可以傳遞參數(shù),這樣就可以根據(jù)不同的場(chǎng)景來(lái)修改裝飾器的行為。

實(shí)際開(kāi)發(fā)中,React 與 Redux 庫(kù)結(jié)合使用時(shí),常常需要寫(xiě)成下面這樣。

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

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

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

2、類(lèi)方法裝飾器

類(lèi)方法裝飾器用來(lái)裝飾類(lèi)的方法

類(lèi)方法裝飾器的參數(shù)

  • target:

  • 裝飾器修飾的類(lèi)方法是靜態(tài)方法:target 為類(lèi)的構(gòu)造函數(shù)

  • 裝飾器修飾的類(lèi)方法是實(shí)例方法:target 為類(lèi)的原型對(duì)象

  • method:被修飾的類(lèi)方法的名稱(chēng)

  • descriptor:被修飾成員的屬性描述符

// descriptor對(duì)象原來(lái)的值如下
{
  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 分別裝飾了實(shí)例方法 instanceMethod 和 靜態(tài)方法 staticMethod。@log 裝飾器的作用是在執(zhí)行原始的操作之前,執(zhí)行 console.log 來(lái)輸出日志。

類(lèi)方法裝飾器傳參

上面實(shí)現(xiàn)的裝飾器在使用時(shí)是不能傳入?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;
  }
}

上面代碼中實(shí)現(xiàn)的裝飾器在使用時(shí)可以傳遞參數(shù),這樣就可以根據(jù)不同的場(chǎng)景來(lái)修改裝飾器的行為。

類(lèi)裝飾器與類(lèi)方法裝飾器的執(zhí)行順序

如果在一個(gè)類(lèi)中,同時(shí)使用裝飾器修飾類(lèi)和類(lèi)的方法,那么裝飾器的執(zhí)行順序是:先執(zhí)行類(lèi)方法的裝飾器,再執(zhí)行類(lèi)裝飾器。

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

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

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

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

上面代碼中的類(lèi)方法裝飾器中,外層裝飾器 @decoratorMethods(1) 先進(jìn)入,但是內(nèi)層裝飾器 @decoratorMethods(2) 先執(zhí)行。類(lèi)裝飾器同理。

利用裝飾器實(shí)現(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);

到此,關(guān)于“es6中裝飾器怎么實(shí)現(xiàn)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!


標(biāo)題名稱(chēng):es6中裝飾器怎么實(shí)現(xiàn)
標(biāo)題鏈接:http://weahome.cn/article/igpjod.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部