ES 7の中を読むjavascript飾り器

3778 ワード

何が飾り物ですか
修飾器はES 7の一つの提案で、その出現は二つの問題を解決できます.
  • 異なるクラス間共有方法
  • コンパイル期間におけるクラスおよび方法の挙動を変更する
  • .
    使い方も簡単です.つまり、種類や方法の上に@符をつけて、vue in typescriptでよく使います.
    以上の二つの用途はよく分からないかもしれません.大丈夫です.最初の例を始めます.
    例1:修飾類
    @setProp
    class User {}
    
    function setProp(target) {
        target.age = 30
    }
    
    console.log(User.age)
    この例では、UserクラスのsetPropを使用してこの方法を修飾し、Userクラスのageの属性を増加させ、setProp方法は3つのパラメータを受信し、私たちは今第1番目に接触し、targetUserクラス自体を表す.
    例2:修飾類(カスタムパラメータ値)
    @setProp(20)
    class User {}
    
    function setProp(value) {
        return function (target) {
            target.age = value
        }
    }
    
    console.log(User.age)
    この例は上の機能とほぼ一致していますが、唯一の違いは値が参照修飾関数から伝わってきたことです.
    例2:飾り方
    class User {
        @readonly
        getName() {
            return 'Hello World'
        }
    }
    
    // readonly    ,         
    function readonly(target, name, descriptor) {
        descriptor.writable = false
        return descriptor
    }
    
    let u = new User()
    //       ,       
    u.getName = () => {
        return 'I will override'
    }
    上記の例では、方法が修正されないようにUserクラスのgetName方法を使用して修飾した.最初のパラメータはもう分かりました.パラメータreadonlyは方法名、つまりnameで、パラメータreadonlyは何ですか?このラインdescriptorを見て、私たちが推測したのも同じです.この3つのパラメータはdescriptor.writable = falseの3つのパラメータに対応しています.Object.definePropertyを設定します.関数を修正できないようにします.
    descriptor.value = 'function (){ console.log('Hello decorator') }'
    出力はdescriptor.writable = falseではなく、Hello Worldであり、修飾器の利点が意識されているのではないか.今から実際の仕事の中で、私達は修飾器を使った例を見てみます.
    アプリケーション1:ログ管理Hello decoratorで包装する時、私達はいつも多くのステップを必要とします.例えば、第1のステップはwebpackファイルを読み、第2のステップはこのファイルを処理し、第3のステップはpackage.jsonファイルをロードし、第4のステップは包装します.直感のために、私達はいつも各ステップでログファイルを印刷します.明らかに日誌の操作と業務コードはまったく関係がないです.日誌と業務を一緒にするべきではないです.このように修飾器を使うのはこの問題を避けるためです.以下のコードです.
    class Pack {
        @log('  package.json  ')
        step1() {
            // do something...
            //        ,     console.log     
            //              
            //     1.console     ,          
            //     2.        console,              
        }
        @log('  webpack    ')
        step2() {
            // do something...
        }
    }
    
    function log(value) {
        return function (target, name, descriptor) {
            //    ,            ,         
            console.log(value)
        }
    }
    
    let pack = new Pack()
    pack.step1()
    pack.step2()
    実際のアプリケーション2:ログインを確認する
    この例は実際の開発でよく使われています.私達はいくつかの操作前に、ユーザーがログインしているかどうかを判断しなければなりません.評価、決済、弾幕送りをしています.前の書き方によって、私達は各方法でユーザーの登録状況を判断してから業務の操作をしなければなりません.前置条件と業務が混同されています.この問題を完璧に解決できます.コードは以下の通りです.
    class User {
        //             
        @checkLogin
        getUserInfo() {
            /**
             *   ,       :
             *      if(checkLogin()) {
             *          //     
             *      }
             *                     
             *         ,              
             */
            console.log('            ')
        }
        //     
        @checkLogin
        sendMsg() {
            console.log('    ')
        }
    }
    
    //         ,      ,        
    function checkLogin(target, name, descriptor) {
        let method = descriptor.value
    
        //       
        let isLogin = true
    
        descriptor.value = function (...args) {
            if (isLogin) {
                method.apply(this, args)
            } else {
                console.log('    ,         ...')
            }
        }
    }
    let u = new User()
    u.getUserInfo()
    u.sendMsg()
    おわりに
    以上はただ修飾器の基本的な応用です.原理を把握して、実際の仕事の中で、自分の応用シーンを考えます.実行前にいくつかの処理を行う必要があるアプリケーションに関連する限り、関数のパラメータ値を修正しても、属性を増加しても、実行の先決条件を変えてもいいです.面に向かってプログラミングすることです.
    ソースと使い方はGitHubに移してください.