JavaScriptの新しい文法詳細解:クラスの私有属性と私有方法


どうして〓印を使うべきですか?
  • 原文:JavaScript's new〓prvate class fields
  • 翻訳者:Fundbug
  • この文章は意訳を採用して、著作権は元の作者の所有になります.
    proposal-class-fieldsとproposal-prvate-methodsは、Classのプライベート属性とプライベート方法を定義しています.この2つの提案はすでにStage 3にあります.これは、基本的に決まっています.新しいECMAScriptバージョンに参加するのを待ちます.実は、最新のChromeはクラスのプライベート属性をサポートしています.
    では、クラスの私有属性と私有方法については、一体何ですか?彼らはどのように働いていますか?なぜ〓〓印を使って定義しますか?
    クラスのプライベート属性文法は以下の通りです.
    class Point {
        #x;
        #y;
    
        constructor(x, y) {
            this.#x = x;
            this.#y = y;
        }
    
        equals(point) {
            return this.#x === point.#x && this.#y === point.#y;
        }
    }
    その文法を2つの部分として理解できます.
  • Classのプライベート属性を定義する
  • Classのプライベート属性を参照する
  • クラスのプライベート属性を定義します.
    私有属性と公共属性の定義方法はほぼ同じですが、属性名の前に、瑭記号を追加する必要があります.
    class Foo {
        publicFieldName = 1;
        #privateFieldName = 2;
    }
    プライベート属性を定義する場合は、値を付けなくても良いです.
    class Foo {
        #privateFieldName;
    }
    クラスのプライベート属性を参照
    私有の属性を引用するにも、〼を使うだけでいいです.
    class Foo {
        publicFieldName = 1;
        #privateFieldName = 2;
        add() {
            return this.publicFieldName + this.#privateFieldName;
        }
    }
    その中で、this.菗は簡略化できます.thisを取り除いても大丈夫です.次の2つの書き方は等価です.
    method() {
      #privateFieldName;
    }
    method() {
      this.#privateFieldName;
    }
    クラス定義でクラスのインスタンスを参照するプライベート属性
    プライベート属性については、直接にクラスのインスタンスを通して引用することはできません.これもプライベート属性の本来の意味です.ただし、クラス定義では除外する場合があります.クラスの実例の私有属性を引用できます.
    class Foo {
        #privateValue = 42;
        static getPrivateValue(foo) {
            return foo.#privateValue;
        }
    }
    
    Foo.getPrivateValue(new Foo()); // >> 42
    このうち、fooはFooの例であり、Classの定義において、私たちはfooを通じてプライベート属性を引用することができます.
    クラスの私有方法
    Classのプライベート属性はproposal-class-fieldsを提案する部分であり、この提案はクラスの属性だけに注目しています.Classのプライベート方法はproposal-class-fieldsを提案する部分です.
    Classのプライベート方法文法は以下の通りです.
    class Foo {
        constructor() {
            this.#method();
        }
        #method() {
            // ...
        }
    }
    関数のプライベート属性にも値を割り当てることができます.
    class Foo {
        constructor() {
            this.#method();
        }
    
        #method = () => {
            // ...
        };
    }
    パッケージ(隠し)のプライベート属性
    私たちは直接にクラスの実例を通して私有属性を引用することができません.クラス定義でのみそれらを引用できます.
    class Foo {
      #bar;
      method() {
        this.#bar; // Works
      }
    }
    let foo = new Foo();
    foo.#bar; // Invalid!
    また、本当にプライベートを行うには、このプライベート属性が存在するかどうかを確認することはできません.したがって、同じ名前の公共属性を定義することを許可する必要があります.
    class Foo {
        bar = 1; // public bar
        #bar = 2; // private bar
    }
    パブリック属性とプライベート属性の同名化が許可されていない場合、同名のパブリック属性のコピーによって、このプライベート属性が存在するかどうかを監視することができます.
    foo.bar = 1; // Error: `bar` is private! (  ,        )
    エラーを出さなくてもいいです
    foo.bar = 1;
    foo.bar; // `undefined` (    ,        )
    subclassについては同じであるべきで、パブリック属性とプライベート属性の同名化も許可される.
    class Foo {
        #fieldName = 1;
    }
    
    class Bar extends Foo {
        fieldName = 2; // Works!
    }
    Classのプライベート属性のパッケージについては、Why is encapulation a goal of this proposalを参照できますか?
    なぜ〓〓印を使いますか?
    多くの人が疑問を持っています.なぜJSは他の言語を勉強できないのですか?なぜ変な〓〓印を使いますか?
    prvateを使うと、コードが楽になります.
    class Foo {
      private value;
    
      equals(foo) {
        return this.value === foo.value;
      }
    }
    なぜprvateを使用しないで私有属性を定義しますか?
    多くの言語はprvateを使って私用属性を定義しています.
    class EnterpriseFoo {
      public bar;
      private baz;
      method() {
        this.bar;
        this.baz;
      }
    }
    これらの言語属性については、私用属性と公共属性の参照方法は同じであるので、彼らはprvateを使用してプライベート属性を定義することができる.
    しかし、JavaScriptにとって、私たちはthis.fieldを使ってプライベート属性を引用することはできません.私有属性を定義し、参照するときは、铅符号を使用して、私有属性と公共属性はよく区別できます.
    なぜ私的属性を引用するときは嚖印が必要ですか?
    私有属性を引用する時、私達はthisが必要です.
  • は、私たちはプライベート属性をカプセル化する必要がありますので、私たちはパブリック属性とプライベート属性の同名を許可する必要があります.したがって、プライベート属性と公的属性の参照方法は違っていなければなりません.この点は前の文でもう詳しく述べました.
  • の共通属性は、this.fieldおよびthis[field]によって参照されてもよいが、プライベート属性はthis[field]をサポートできない.そうでないとプライベート属性のプライバシーを破壊する.例は以下の通りである.
    class Dict extends null {
        #data = something_secret;
        add(key, value) {
            this[key] = value;
        }
        get(key) {
            return this[key];
        }
    }
    
    new Dict().get("#data"); //       
    したがって、私有属性と公的属性の参照方法は異なる必要があります.そうでないと、this[field]文法が破壊されます.
  • 私有属性は、公的属性の参照方法と同じであれば、属性が公共か私有かを確認する必要があります.これは深刻な性能問題を引き起こします.
  • この文章はCreative Commons Attribution 4.0 Internationl Licenseに準拠しています.
    参照
  • Why is encapulation a goal of this proposal?
  • Funebugについて
    FunndebugはJavaScript、微信小プログラム、微信小ゲーム、支払宝小プログラム、React Native、Node.js、JavaオンラインでリアルタイムBUG監視を適用します.2016年に双十一が正式にオンラインしてから、Fundebugは累計で10億+エラー事件を処理しました.有料顧客はGoogle、360、金山軟件、庶民網など多くのブランド企業があります.皆さん、無料で試用してください.
    著作権声明
    転載する時、作者のFunebugと本文の住所を明記してください.https://blog.fundebug.com/201...