ES 6 classクラスでのプライベート変数の定義

3324 ワード

ES 6 classクラスでのプライベート変数の定義
classクラスの不足
見たところ、es 6の中のclassの出現はJSと伝統的なOOP言語の距離を近づけた.しかし、それは単なる文法糖であり、従来のOOP言語のような機能を実現することはできない.その中で,比較的大きな痛み点は私有変数の問題である.
プライベート変数とは?プライベート変数とは、クラス内でしかアクセスできない変数であり、外部ではアクセスできない変数です.開発では、多くの変数やメソッドが他の人にアクセスしたくないので、プライベート変数として定義し、他の人に使用されないようにすることができます.Javaではprivateを使用してプライベート変数を実装できますが、残念ながらJSにはこの機能はありません.
次のコードを見てみましょう.
class A {
    constructor(x) {
        this.x = x
    }
    
    //           x
    showX () {
        return this.x
    }
}

let a = new A(1)

//     x  
a.x // 1

方法showXによってxの値を暴露することを意図しているが,a.xによってxの値に直接アクセスできることがわかる.
これはコードのパッケージ性に影響を及ぼすことは明らかである.これらのプロパティはforを使用できることを知っておく必要があります.inが遍歴してきた.
したがってclassのプライベート変数機能を実現する必要がある.
classプライベート変数の実装
class自体はプライベート変数の機能を提供していませんが、プライベート変数のような機能をいくつかの方法で実現することができます.
  • 約定命名はまず、現在最も広く使用されている方法である:約定命名.この方法は簡単です.チームがプライベート変数を表す命名方法を約束します.一般的には、プライベート変数の名前の前に下線を引きます.コードは以下の通りです.
    class A {
        constructor(x) {
            // _x        
            this._x = x
        }
    
     showX () {
         return this._x
     }
    
    }
    
    let a = new A(1)
    
    // _x        
    a._x        // 1
    a.showX()   //1
    では、この方法の最大の利点は簡単で便利であることがわかります.そのため、多くのチームがこの方法を採用しています.しかし、この方法は本質的に問題を解決していない.forを使うと...inは依然としていわゆる私有変数を遍歴することができ,治標不治本と言える.しかし、この方法は、約束の規範を通じて他人がコードを読むのを便利にすることを肯定する価値がある.
  • 閉包閉包は多くの場合モジュール化問題を解決するために用いられ,私有変数も本質的にモジュール化問題であることが明らかになったので,閉包を用いて私有変数の問題を解決することもできる.コンストラクション関数で局所変数を定義し,メソッド参照によりこの変数が真のプライベート変数となる.
    class A {
        constructor (x) {
            let _x = x
            this.showX = function () {
                return _x
            }
        }
    }
    
    let a = new A(1)
    //     
    a._x        // undefined
    //     
    a.showX()   // 1
    この方法の最大の利点は、プライベート変数の問題を本質的に解決することである.しかし、この場合、プライベート変数を参照する方法はプロトタイプチェーンに定義できず、構造関数、すなわちインスタンスにのみ定義できるという大きな問題がある.これは2つの欠点をもたらしました.
  • 追加のパフォーマンスオーバーヘッド
  • 構造関数には方法が含まれており、比較的肥大化しており、後続のメンテナンスに一定のトラブルをもたらしている
  • 進級版閉包方式構造関数の内部で閉包を定義するのが面倒である以上、classの外に置けばいいのではないでしょうか.
  • IIFE(直ちに関数式を実行する)によって閉パケット
  • を確立することができる.
  • では、変数とclassが確立され、class参照変数によってプライベート変数が実現される.

  • コードは以下の通りである:
    //       IIFE,   A
    const A = (function() {
        //       _x
        let _x
    
     class A {
         constructor (x) {
             //        _x
             _x = x
         }
    
         showX () {
             return _x
         }
     }
    
     return A
    
    })()
    
    let a = new A(1)
    
    //     
    a._x        // undefined
    //     
    a.showX()   //1
    は、この方法が以前の閉パッケージの問題を完璧に解決したことを発見することができ、書き方が比較的複雑であるだけでなく、IIFEを追加する必要があり、少し追加の性能オーバーヘッドがある.
  • 注:IIFEを使用せずに、プライベート変数をグローバルに直接配置することもできますが、これはパッケージングに不利です.

  • Symbolこの方式はSymbolの唯一性を利用しています.敵の最大の優位性は味方のkey値を知っていることです.私はkey値を唯一にしました.敵は私のkey値を知らないので、アクセスできません.(人質は今回の任務の鍵であり、敵が人質を持たなくなったとき、任務も完成した)コードは以下の通りである:
    class A {
        constructor (x) {
    
            //   symbol
         const _x = Symbol('x')
    
            //   symbol      
            this[_x] = x
        }
    
        showX () {
            return this[_x]
        }
    }
    
    let a = new A(1)
    
    // 1.      
    a[_x]    //    Uncaught ReferenceError: _x is not defined
    
    // 2.      
    //          Symbol
    const x = Symbol('x')
    a[x]        //     ,undefined
    
    // 3.      ,    (  )
    a.showX()   //1
    結果から見ると、class私有変数を完璧に実現した.
  • 転載先:https://www.cnblogs.com/guojbing/p/10990267.html