ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript'の新しいプライベートクラスフィールド、およびそれらの使用方法

JavaScript'の新しいプライベートクラスフィールド、およびそれらの使用方法

Joseph Gordon-Levitt
Joseph Gordon-Levittオリジナル
2025-02-10 14:30:15757ブラウズ

JavaScript's New Private Class Fields, and How to Use Them

ES6はJavaScriptのクラスを導入しますが、複雑なアプリケーションの場合、それらはあまりにも単純である可能性があります。クラスフィールド(クラス属性とも呼ばれます)は、プライベートメンバーと静的メンバーを持つコンストラクターを簡素化するように設計されています。この提案は現在、TC39フェーズ3:候補段階にあり、ES2019(ES10)に追加される可能性があります。 Node.js 12、Chrome 74、およびBabelは現在、私的フィールドをサポートしています。クラスフィールドがどのように実装されるかを理解する前に、ES6クラスをレビューすると便利です。 この記事は2020年に更新されました。詳細なJavaScriptの知識については、本「JavaScript:NewbieからNinja、Second Edition」を読んでください。

キーポイント

    ES6はJavaScriptのクラスを導入しますが、複雑なアプリケーションの場合、それらはあまりにも単純である可能性があります。 ES2019のクラスフィールドは、ES2019(ES10)に追加できるプライベートおよび静的メンバーでコンストラクターを簡素化するように設計されています。
  • 新しいクラスフィールドの実装により、クラスの上部にあるコンストラクターの外側のパブリックプロパティの初期化が可能になります。コンストラクターがまだ必要な場合、初期化は実行される前に実行されます。
  • ES2019のクラスフィールドを使用すると、ハッシュ#プレフィックスを使用してプライベートクラスフィールドを宣言します。これにより、クラスの外部からではなく、クラスの内部方法でのみフィールドにアクセスできます。
  • クラスフィールドでのプライベート性を表すための#の使用は、主に秘密キーワードほど直感的ではないためです。ただし、#シンボルはクラスの定義の外側に無効であり、プライベートフィールドがプライベートのままであることを保証します。
  • ES2019クラスフィールドの当面の利点は、クリーナーReactコードです。 ES6 =>を使用して関数として割り当てることができます。
es6カテゴリの基本

C、C#、Java、PHPなどの言語の開発者は、JavaScriptのオブジェクト指向の継承モデルによって混同される場合があります。したがって、ES6はクラス

を導入しました。それらは主に構文砂糖ですが、オブジェクト指向プログラミングのより馴染みのある概念を提供します。クラスは、そのタイプのオブジェクトがどのように動作するかを定義するオブジェクトテンプレート

です。次の動物クラスでは、一般的な動物を定義します(通常、クラスは初期の大文字で表され、オブジェクトや他のタイプから区別されます): クラス宣言は常に厳密なモードで実行されます。 「Strictを使用する」を追加する必要はありません。タイプ動物のオブジェクトを作成するときに、

コンストラクターメソッドが実行されます。通常、初期プロパティを設定し、他の初期化を処理します。 Speak()およびWalk()は、より多くの機能を追加するインスタンスメソッドです。これで、新しいキーワードを使用して、このクラスからオブジェクトを作成できます。
<code class="language-javascript">class Animal {

  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {

    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;

  }

  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }

  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }

}</code>

getter and setter

<code class="language-javascript">let rex = new Animal('Rex', 4, 'woof');
rex.speak();          // Rex says "woof"
rex.noise = 'growl';
rex.speak();          // Rex says "growl"</code>

setter は、値を定義するためにのみ使用される特別な方法です。同様に、getter

は、戻り値のみの特別な方法です。たとえば、

サブクラスまたはサブクラス

通常、1つのクラスを別のクラスに使用することが可能です。人間のクラスは、拡張キーワードを使用して、動物クラスのすべての特性と方法を継承できます。プロパティと方法は、必要に応じて追加、削除、または変更して、人間のオブジェクトをより簡単かつ明確に作成することができます。

<code class="language-javascript">class Animal {

  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {

    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;

  }

  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }

  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }

}</code>
スーパーは親クラスを指します。そのため、通常、コンストラクターで呼び出される最初の呼び出しです。この例では、Human Speak()メソッドは、動物で定義された方法を上書きします。これで、人間のオブジェクトのインスタンスを作成できます。

<code class="language-javascript">let rex = new Animal('Rex', 4, 'woof');
rex.speak();          // Rex says "woof"
rex.noise = 'growl';
rex.speak();          // Rex says "growl"</code>
静的メソッドとプロパティ

静的キーワードを使用してメソッドを定義することで、オブジェクトインスタンスを作成せずにクラスで呼び出すことができます。 Math.pi定数を考慮してください:PIプロパティにアクセスする前にMathオブジェクトを作成する必要はありません。 ES6は他の言語と同じ静的プロパティをサポートしていませんが、プロパティをクラス定義自体に追加できます。たとえば、人間のクラスは、作成された人間のオブジェクトの数をカウントするために適応できます。

クラスの静的カウントゲッターは、それに応じて人間の数を返します。

<code class="language-javascript">class Animal {

  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {

    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;

  }

  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }

  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }

  // setter
  set eats(food) {
    this.food = food;
  }

  // getter
  get dinner() {
    return `${this.name} eats ${this.food || 'nothing'} for dinner.`;
  }

}

let rex = new Animal('Rex', 4, 'woof');
rex.eats = 'anything';
console.log( rex.dinner );  // Rex eats anything for dinner.</code>

ES2019クラスフィールド(

new
<code class="language-javascript">class Human extends Animal {

  constructor(name) {

    // 调用Animal构造函数
    super(name, 2, 'nothing of interest');
    this.type = 'human';

  }

  // 重写Animal.speak
  speak(to) {

    super.speak();
    if (to) console.log(`to ${to}`);

  }

}</code>

新しいクラスフィールドの実装により、クラスの上部にあるコンストラクターの外側のパブリックプロパティの初期化が可能になります。 これは次のとおりです

コンストラクターがまだ必要な場合は、初期イザーが実行される前に実行されます。

<code class="language-javascript">let don = new Human('Don');
don.speak('anyone');        // Don says "nothing of interest" to anyone

don.eats = 'burgers';
console.log( don.dinner );  // Don eats burgers for dinner.</code>
静的クラスフィールド

上記の例では、クラスオブジェクトを定義した後、静的プロパティがクラス定義オブジェクトに不可能な方法で追加されます。クラスフィールドを使用する必要はありません:

<code class="language-javascript">class Human extends Animal {

  constructor(name) {

    // 调用Animal构造函数
    super(name, 2, 'nothing of interest');
    this.type = 'human';

    // 更新Human对象的计数
    Human.count++;

  }

  // 重写Animal.speak
  speak(to) {

    super.speak();
    if (to) console.log(`to ${to}`);

  }

  // 返回人类对象的个数
  static get COUNT() {
    return Human.count;
  }

}

// 类的静态属性本身 - 不是其对象
Human.count = 0;</code>

これは次のとおりです

プライベートクラスフィールド

ES6クラスのすべての属性はデフォルトで公開されており、

クラスの外部でチェックまたは変更できます。上記の動物の例では、Eats Setterを呼び出すことなく、食​​品の財産の変更を妨げるものはありません:console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 0 let don = new Human('Don'); console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 1 let kim = new Human('Kim'); console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 2

他の言語では、通常、プライベート属性の宣言を許可します。これはES6では不可能であるため、開発者はしばしばアンダースコアコンベンション(_PropertyName)、閉鎖、シンボル、またはこの問題を解決するために使用します。アンダースコアは開発者にヒントを与えますが、彼らがプロパティにアクセスするのを妨げることはできません。 ES2019では、プライベートクラスフィールドはハッシュ#プレフィックスを使用して定義されています:

<code class="language-javascript">class MyClass {

  a = 1;
  b = 2;
  c = 3;

}</code>

プライベートメソッド、ゲッター、またはセッターを定義できないことに注意してください。 TC39フェーズ3:ドラフト提案では、バベルで実装されている名前にハッシュ#プレフィックスを使用することを推奨しています。たとえば、

すぐにメリット:より簡潔なReactコード!

<code class="language-javascript">class MyClass {

  constructor() {
    this.a = 1;
    this.b = 2;
    this.c = 3;
  }

}</code>

Reactコンポーネントには通常、DOMイベントに結合したメソッドがあります。これがコンポーネントに解決するためには、それに応じて各メソッドをバインドする必要があります。たとえば、

<code class="language-javascript">class MyClass {

  x = 1;
  y = 2;
  static z = 3;

}

console.log( MyClass.z ); // 3</code>

IncCountがES2019クラスフィールドとして定義される場合、ES6 =&gt;を使用して関数として割り当てることができます。バインディングステートメントを追加する必要はありません:

<code class="language-javascript">class MyClass {

  constructor() {
    this.x = 1;
    this.y = 2;
  }

}

MyClass.z = 3;

console.log( MyClass.z ); // 3</code>

クラスフィールド:改善しましたか?

ES6クラスの定義は単純すぎます。 ES2019クラスフィールドには、コードが少なくなり、読みやすさが向上し、オブジェクト指向プログラミングの興味深い可能性を実装します。 #を使用すると、プライベートがいくつかの批判を受けています。これは、主に醜く、スキルのように感じるからです。ほとんどの言語は秘密のキーワードを実装するため、クラス外のメンバーを使用しようとすると、コンパイラによって拒否されます。 JavaScriptが解釈されます。次のコードを検討してください:

<code class="language-javascript">class Animal {

  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {

    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;

  }

  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }

  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }

}</code>

これにより、最後の行にランタイムエラーが発生しますが、プロパティを設定しようとすることによる深刻な結果です。 JavaScriptは意図的に寛容であり、ES5はあらゆるオブジェクトのプロパティを変更できます。不器用ですが、#シンボルはクラス定義の外側に無効です。 Myobjectにアクセスしようとします。この議論は継続されますが、クラスフィールドは既に複数のJavaScriptエンジンで採用されています。それらは存在し続けます。

JavaScriptのプライベートクラスフィールドについての

FAQ(FAQS)JavaScriptプライベートクラスフィールドを使用することの利点は何ですか?

JavaScriptのプライベートクラスフィールドは、クラス内のデータをカプセル化または非表示にする方法を提供します。これは、オブジェクト指向プログラミングの基本原則です。このカプセル化により、オブジェクトの内部状態は、クラスが明示的に定義された方法でのみ変更できることが保証されます。これにより、コードは、外部コードが予期しない方法でオブジェクトの状態を誤って変更することを防ぐため、より堅牢で予測可能になります。さらに、プライベートフィールドは、クラスのインターフェイスを簡素化するのに役立ちます。これは、外の世界にさらされるプロパティと方法の数を減らすためです。

JavaScriptでプライベートクラスフィールドを宣言する方法は?

JavaScriptでは、フィールド名の前にハッシュ(#)シンボルを追加することにより、プライベートクラスフィールドが宣言されます。たとえば、クラスで「値」という名前のプライベートフィールドを宣言するには、#Valueを書くことができます。このフィールドは、クラスの外部からではなく、クラスの内部方法でのみアクセスできます。

クラスの外からプライベートクラスフィールドにアクセスできますか?

いいえ、JavaScriptのプライベートクラスフィールドには、クラスの外部からアクセスできません。これは設計によるものです。なぜなら、プライベートフィールドの主な用途の1つは、外部から内部データを隠すことだからです。クラスの外部からプライベートフィールドにアクセスしようとすると、JavaScriptは構文エラーをスローします。

公共フィールドでプライベートクラスフィールドを使用できますか?

はい、JavaScriptクラスにはプライベートフィールドとパブリックフィールドの両方があります。パブリックフィールドはプライベートフィールドと同じ方法で宣言されますが、ハッシュ(#)プレフィックスはありません。クラス内からのみアクセスできるプライベートフィールドとは異なり、クラスの内外からのパブリックフィールドにアクセスおよび変更できます。

プライベートクラスフィールドは、JavaScriptのプライベートメソッドとどのように違いますか?

JavaScriptのプライベートクラスフィールドとプライベートメソッドには同様の用途があり、どちらも外の世界からクラスの内部の詳細を隠す方法を提供します。ただし、使用方法は異なります。プライベートフィールドは、クラス内でのみアクセスできるデータを保存するために使用されますが、プライベートメソッドはクラス内でのみ呼び出される機能です。

すべてのJavaScript環境でプライベートクラスフィールドを使用できますか?

プライベートクラスフィールドはJavaScriptの比較的新しい機能であるため、すべての環境がそれをサポートしているわけではありません。執筆時点では、Chrome、Firefox、Safariを含むほとんどの主要なブラウザの最新バージョンがプライベートフィールドをサポートしています。ただし、Internet Explorerはそれらをサポートしていません。すべてのブラウザで実行されるコードを作成する必要がある場合は、Babelなどのコンバーターを使用して、コードを古いブラウザが理解できるフォームに変換する必要がある場合があります。

クラスの内部方法でプライベートクラスフィールドを使用する方法は?

クラスの内部メソッドでプライベートクラスフィールドを使用するには、単にその名前(ハッシュ(#)シンボルが付いているフィールド)を参照してください。たとえば、「値」と呼ばれるプライベートフィールドがある場合、このような方法でアクセスできます。これ。#値。

サブクラスでプライベートクラスフィールドを使用できますか?

はい、プライベートクラスフィールドはJavaScriptのサブクラスで使用できます。ただし、各サブクラスには、スーパークラスや他のサブクラスと共有されていない独自の独立したプライベートフィールドセットがあります。これは、サブクラスで宣言されたプライベートフィールドがスーパークラスのプライベートフィールドと同じ名前である場合、2つのフィールドは完全に独立しており、互いに干渉しないことを意味します。

静的メソッドでプライベートクラスフィールドを使用できますか?

いいえ、JavaScriptのプライベートクラスフィールドは、静的な方法では使用できません。これは、静的方法がクラスのインスタンスではなくクラス自体に関連付けられており、プライベートフィールドにはクラスのインスタンスでのみアクセスできるためです。

JavaScriptのプライベートクラスフィールドを反復することはできますか?

いいえ、JavaScriptのプライベートクラスフィールドは、オブジェクトのプロパティイテレーションに含まれていません。これは設計によるものです。なぜなら、プライベートフィールドの主な用途の1つは、外部から内部データを隠すことだからです。オブジェクトのプロパティを反復する必要がある場合は、代わりにパブリックフィールドまたはメソッドを使用する必要があります。

この応答は、元の画像形式と配置を維持し、コードの例を保持しながらテキストを言い換えます。

以上がJavaScript&#x27;の新しいプライベートクラスフィールド、およびそれらの使用方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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