JavaScript のプライベート クラス フィールドと TypeScript のプライベート修飾子の詳細な説明

JavaScript のプライベート クラス フィールドと TypeScript のプライベート修飾子の詳細な説明

JavaScript のプライベート クラス フィールドとプライバシーの必要性

これまで、JavaScript には、もちろん従来のクロージャを除いて、変数へのアクセスを保護するネイティブ メカニズムはありませんでした。

クロージャは、人気のあるモジュール パターンなど、JavaScript における多くのプライバシーに似たパターンの基礎となります。しかし、近年の ECMAScript 2015 クラスの使用により、開発者はクラス メンバーのプライバシーをより厳密に制御する必要性を感じるようになりました。

クラス フィールドの提案 (執筆時点ではステージ 3) では、プライベート クラス フィールドを導入することでこの問題を解決しようとしています。

どのような見た目か見てみましょう。

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

以下はプライベート フィールドを持つ JavaScript クラスです。「パブリック」メンバーとは異なり、各プライベート フィールドはアクセスする前に宣言する必要があることに注意してください。

クラス Person {
  #年;
  #名前;
  #姓;
  コンストラクタ(名前、姓、年齢) {
    this.#name = 名前;
    this.#surname = 姓;
    this.#age = 年齢;
  }
  フルネームを取得する() {
    `${this.#name} + ${this.#surname}` を返します。
  }
}

プライベート クラス フィールドはクラス外部からアクセスできません。

クラス Person {
  #年;
  #名前;
  #姓;
  コンストラクタ(名前、姓、年齢) {
    this.#name = 名前;
    this.#surname = 姓;
    this.#age = 年齢;
  }
  フルネームを取得する() {
    `${this.#name} + ${this.#surname}` を返します。
  }
}
const marta = new Person("Marta", "Cantrell", 33);
console.log(marta.#age); // 構文エラー

これが本当の「プライバシー」です。 TypeScript について少しでも知っている場合は、「ネイティブ」プライベート フィールドと TypeScript の private 修飾子の共通点は何なのか疑問に思うかもしれません。

答えは「いいえ」です。しかし、なぜ?

TypeScriptのprivate修飾子

従来のプログラミング言語の経験がある開発者は、TypeScript の private 修飾子に精通している必要があります。つまり、このキーワードの目的は、クラス外からのクラス メンバーへのアクセスを拒否することです。

ただし、TypeScript は JavaScript の上のレイヤーであり、TypeScript コンパイラーは private を含むすべての派手な TypeScript コメントを削除する必要があることを忘れないでください。

つまり、次のクラスは必要な動作を実行しません。

クラス Person {
  プライベート年齢:番号;
  プライベート名: 文字列;
  個人の姓: 文字列;
  コンストラクター(名前: 文字列、姓: 文字列、年齢: 数値) {
    this.name = 名前;
    this.surname = 姓;
    this.age = 年齢;
  }
  フルネームを取得する() {
    `${this.name} + ${this.surname}` を返します。
  }
}
const liz = new Person("Liz", "Cantrill", 31);
// @ts を無視
コンソールにログ出力します。

//@ts-ignore がない場合、 liz.age にアクセスすると TypeScript でエラーが発生するだけですが、コンパイル後には次の JavaScript コードが生成されます。

「厳密な使用」;
var Person = /** @class */ (function () {
    関数 Person(名前, 姓, 年齢) {
        this.name = 名前;
        this.surname = 姓;
        this.age = 年齢;
    }
    Person.prototype.getFullName = 関数 () {
        this.name + " + " + this.surname を返します。
    };
    Person を返します。
}());
var liz = new Person("Liz", "Cantrill", 31);
console.log(liz.age); // 31

予想どおり、liz.age をコンソールに出力できます。ここでの重要な点は、TypeScript の private はそれほどプライベートではなく、TypeScript レベルでは便利に感じられるだけで、「本当のプライバシー」ではないということです。

それでは、TypeScript の「ネイティブ」プライベート クラス フィールドに移りましょう。

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

TypeScript 3.8 では ECMAScript のプライベート フィールドがサポートされますが、TypeScript のプライベート修飾子と混同しないでください。

以下は TypeScript のプライベート クラス フィールドを持つクラスです。

クラス Person {
    #年齢: 数字;
    #名前: 文字列;
    #姓: 文字列;
    コンストラクター(名前:文字列、姓:文字列、年齢:数値) {
        this.#name = 名前;
        this.#surname = 姓;
        this.#age = 年齢;
    }
    フルネームを取得する() {
        `${this.#name} + ${this.#surname}` を返します。
    }
}

型注釈を除けば、ネイティブ JavaScript と違いはありません。メンバーには外部からアクセスできません。しかし、TypeScript のプライベート フィールドの本当の問題は、内部的に WeakMap が使用されていることです。

このコードをコンパイルするには、tsconfig.json でターゲット コンパイル バージョンを調整する必要があります。これは少なくとも ECMAScript 2015 である必要があります。

{
  "コンパイラオプション": {
    "ターゲット": "es2015",
    "厳密": 真、
    "lib": ["dom","es2015"]
  }
}

これは、対象ブラウザによっては問題になる可能性があり、WeakMap のポリフィルを提供する予定がない限り、新しい凝った構文を書くだけでも大変な作業になります。

JavaScript では、新しい構文を使用したい一方で、多くのポリフィルでユーザー エクスペリエンスを低下させたくないという緊張関係が常に存在します。

一方、新しいブラウザにリリースする場合でも、プライベート クラス フィールドについて心配する必要はありません。少なくとも今はそうです。 Firefox でさえこの提案を実装していません。

以上がJavaScriptのプライベートクラスフィールドとTypeScriptのプライベート修飾子の詳しい説明です。JavaScriptのプライベートクラスフィールドとTypeScriptのプライベート修飾子の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • JavaScriptとTypeScriptの関係
  • JS デコレータ パターンと TypeScript デコレータ
  • MD5ハッシュを取得する際のPythonとJSの違いは何ですか
  • Easy Languageでjsを使用してmd5暗号化を実装する方法の詳細な説明
  • TypeScript および JavaScript プロジェクトに MD5 チェックサムを導入する

<<:  win10でのmysql5.7.21解凍バージョンのインストールチュートリアル

>>:  Linuxで静的ネットワーク接続を構成する方法

推薦する

CSS を使用して 3 列のアダプティブ レイアウト (両側は固定幅、中央はアダプティブ) を実現します。

いわゆる 3 列適応レイアウトとは、両側の幅が固定され、中央のブロックの幅が適応されることを意味しま...

MySQLは複数テーブル関連統計(サブクエリ統計)の例を実装します

この記事では、例を使用して、MySQL で複数テーブルの関連統計を実装する方法について説明します。ご...

MySQLデータベーステーブルの容量を確認する方法の例

この記事では、MySQL のデータベース テーブルの容量を確認するためのコマンド ステートメントを紹...

iframeフレームはIEブラウザで白い背景を透明に設定します

最近、プロジェクトを進める過程で、ページの階層構造を描画するために iframe を頻繁に使用する必...

Linux での chmod コマンドの使用方法の詳細な説明

chmod コマンド構文chmod コマンドを使用する場合の正しい構文は次のとおりです。 chmod...

Linux のスクリーンコマンドとその使い方

画面紹介Screen は、コマンドライン端末切り替え用に GNU プロジェクトによって開発されたフリ...

ふるい抽選を実施するミニプログラム

この記事の例では、ふるい抽選を実装するためのミニプログラムの具体的なコードを参考までに共有しています...

既存のMySQLデータベースの文字セットを統一する方法

序文データベースでは、一部のデータ テーブルとデータは latin1 であり、一部のデータ テーブル...

HTML ウェブページでのアンカー(名前付きアンカー)の使用の概要

以下の情報はインターネットから収集したものです1. アンカーは、Web ページ作成におけるハイパーリ...

CSSを使用してファイルアップロードパターンを描画する

以下に示すように、あなたならどのようにそれを達成しますか: 通常、フォントアイコンを使用して中央にプ...

フォント名に従ってフォントを呼び出すと、ブラウザに必要なフォントが表示されます。

質問 1: ブラウザに必要なフォントを表示するように指示するにはどうすればよいでしょうか? フォント...

Dockerコンテナ間の通信を実装する方法

シナリオ: laradock 開発環境 (php7.3+mysql5.7) がローカルに構築されてい...

MongoDB の起動エラーを解決します: 共有ライブラリのロード中にエラーが発生しました: libstdc++.so.6: 共有オブジェクト ファイルを開けません:

MongoDB を起動すると、プロンプトは次のようになります。共有ライブラリのロード中にエラーが発...

JavaScript のガベージコレクションの仕組みの詳細な説明

目次ガベージコレクション (GC) はなぜ必要なのでしょうか?ガベージコレクションとは廃棄物の発生ガ...

Vueインスタンスで$refsを使用する際の注意点

開発の過程では、インスタンスの vm.$refs(this.$refs) を使用して、ref で登録...