ホームページ >ウェブフロントエンド >フロントエンドQ&A >es6 モディファイアは何に使用されますか?

es6 モディファイアは何に使用されますか?

青灯夜游
青灯夜游オリジナル
2023-01-30 19:29:501714ブラウズ

ES6 では、デコレータは、「@関数名」として記述される ES5 の「Object.defineProperty」メソッドに依存して、クラスおよびクラス メソッドに注釈を付けたり変更したりするために使用されます。デコレータは実際には関数であり、通常は次のように記述されます。クラスとクラスメソッドの前に。修飾子をクラス、メソッド、および属性パラメータに挿入して、クラス、属性、メソッド、およびパラメータの機能を拡張できます。

es6 モディファイアは何に使用されますか?

このチュートリアルの動作環境: Windows 7 システム、ECMAScript バージョン 6、Dell G3 コンピューター。

デコレータ パターンを使用すると、既存のオブジェクトの構造を変更せずに、新しい機能を追加できます。このタイプのデザイン パターンは構造パターンであり、既存のクラスのラッパーとして機能します。

このモードは、元のクラスをラップする装飾クラスを作成し、クラス メソッド シグネチャの整合性を維持しながら追加機能を提供します。

ES6 デコレータ (Decorator)

ES6 では、デコレータ (Decorator) は、クラスおよびクラス メソッドに注釈を付けたり変更したりするために使用されるクラス関連の構文です。

デコレータは実際には関数であり、通常はクラスおよびクラス メソッドの前に配置されます。

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

上記のコードでは 2 つのデコレータが使用されており、そのうち @decorateClass() デコレータはクラス自体の Add で使用されています。または、クラスの機能を変更します。 @decorateMethods() デコレータは、クラス メソッドに注釈を付けたり変更したりするためにクラス メソッドで使用されます。

2 種類のデコレータ (デコレータ)

デコレータは、関数プロモートがあるため、関数ではなくクラスとクラス メソッドにのみ使用できます。

#デコレータはクラスとクラス メソッドにのみ使用できます。2 種類のデコレータの使用法をそれぞれ見てみましょう

クラス デコレータ

クラス デコレータはクラス全体を装飾するために使用されます

クラス デコレータのパラメータ

ターゲット: クラス自体もクラスのコンストラクターと同等です: Class.prototype 。コンストラクタ。

@decorateClass
class Example {
    //...
}

function decorateClass(target) {
    target.isTestClass = true
}
上記のコードに示すように、デコレータ @decorateClass は Example クラス全体の動作を変更し、静的属性 isTestClass を追加します。 Example クラスに。 Decorator は関数です。decoratorClass 関数のパラメータ ターゲットは Example クラス自体であり、これはクラス コンストラクタ Example.prototype.constructor.

パラメータを渡す Decorator と同等でもあります。 #上記で実装されたデコレータは、使用時にパラメータで渡すことはできません。デコレータの使用時にパラメータで渡したい場合は、デコレータの外側に関数の層をカプセル化できます##
@decorateClass(true)
class Example {
    //...
}

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

上記のコードで実装されたデコレータは、使用時にパラメータを渡すことができるため、さまざまなシナリオに応じてデコレータの動作を変更できます。
実際の開発では、React を Redux ライブラリと組み合わせて使用​​する場合、次のように記述する必要があることがよくあります。

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

デコレータを使用すると、上記のコードを書き直すことができます。
#
@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {}

クラス メソッド デコレータ
クラス メソッド デコレータは、クラス メソッド デコレータのメソッドを修飾するために使用されます。 class

クラス メソッド デコレータのパラメータ

target:

クラス メソッドが変更されました。デコレータ これは静的メソッドです。ターゲットはクラスのコンストラクタです。
  • #デコレータによって変更されたクラス メソッドはインスタンス メソッドです。ターゲットはクラスのプロトタイプ オブジェクトです。

  • メソッド: 変更されたクラスメソッドの名前

  • ##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と静的メソッドstaticMethodです。 @log デコレータの機能は、元の操作を実行する前に console.log を実行してログを出力することです。
クラス メソッド デコレータによるパラメータの受け渡し
上記で実装されたデコレータは、使用時にパラメータとして渡すことができません。デコレータを使用したい場合は、パラメータを渡す必要があります。デコレータの外側に関数の別の層をカプセル化できます。

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;
  }
}

上記のコードで実装されたデコレータは、使用時にパラメータを渡すことができます。つまり、デコレータの動作はさまざまなシナリオに応じて変更できます。

クラス デコレータとクラス メソッド デコレータの実行順序
クラス内で、クラスとクラス メソッドを同時に修飾するためにデコレータが使用される場合、デコレータ 実行順序は、最初にクラス メソッド デコレータを実行し、次にクラス デコレータを実行します。
同じクラスまたは同じクラス メソッドに複数のデコレータがある場合、玉ねぎの皮をむくようなもので、最初に外側から内側に入り、次に内側から外側に向かって実行されます。

// 类装饰器
function decoratorClass(id){
    console.log('decoratorClass evaluated', id);

    return (target) => {
        // target 类的构造函数
        console.log('target 类的构造函数:',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 类的构造函数: [Function: Example]
// decoratorClass executed 2
// target 类的构造函数: [Function: Example]
// decoratorClass executed 1

如上面代码中,会先执行类方法的装饰器 @decoratorMethods(1) 和 @decoratorMethods(2),执行完后再执行类装饰器 @decoratorClass(1) 和 @decoratorClass(2)

上面代码中的类方法装饰器中,外层装饰器 @decoratorMethods(1) 先进入,但是内层装饰器 @decoratorMethods(2) 先执行。类装饰器同理。

利用装饰器实现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 モディファイアは何に使用されますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。