From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../classes/private_class_fields/index.html | 207 +++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 files/ja/web/javascript/reference/classes/private_class_fields/index.html (limited to 'files/ja/web/javascript/reference/classes/private_class_fields/index.html') diff --git a/files/ja/web/javascript/reference/classes/private_class_fields/index.html b/files/ja/web/javascript/reference/classes/private_class_fields/index.html new file mode 100644 index 0000000000..6310aa5092 --- /dev/null +++ b/files/ja/web/javascript/reference/classes/private_class_fields/index.html @@ -0,0 +1,207 @@ +--- +title: プライベートクラスフィールド +slug: Web/JavaScript/Reference/Classes/Private_class_fields +tags: + - Classes + - JavaScript + - Language feature +translation_of: Web/JavaScript/Reference/Classes/Private_class_fields +--- +
{{JsSidebar("Classes")}}
+ +

クラスのプロパティはデフォルトで公開されており、クラスの外で調べたり変更したりすることができます。しかし、ハッシュ # 接頭辞を使ってプライベートなクラスフィールドを定義できるようにする実験的な提案があります。

+ +

構文

+ +
class ClassWithPrivateField {
+  #privateField
+}
+
+class ClassWithPrivateMethod {
+  #privateMethod() {
+    return 'hello world'
+  }
+}
+
+class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+}
+
+ +

+ +

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

+ +

プライベートフィールドは、クラスのコンストラクタ上でクラス宣言の内部からアクセスできます。

+ +

静的変数は静的メソッドからのみ呼び出せるという制限はまだあります。

+ +
class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+
+  static publicStaticMethod() {
+    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42
+    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD
+  }
+}
+
+console.assert(ClassWithPrivateStaticField.publicStaticMethod() === 42)
+ +

プライベートスタティックフィールドは、クラスの評価時にクラスのコンストラクタに追加されます。

+ +

プライベートスタティックフィールドには、プライベートスタティックフィールドを定義しているクラスのみが、そのフィールドにアクセスできるという出自制限があります。

+ +

これは、this を使用しているときに予期しない動作をする可能性があります。

+ +
class BaseClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+
+  static basePublicStaticMethod() {
+    this.#PRIVATE_STATIC_FIELD = 42
+    return this.#PRIVATE_STATIC_FIELD
+  }
+}
+
+class SubClass extends BaseClassWithPrivateStaticField { }
+
+let error = null
+
+try {
+  SubClass.basePublicStaticMethod()
+} catch(e) { error = e}
+
+console.assert(error instanceof TypeError)
+
+ +

プライベートインスタンスフィールド

+ +

プライベートインスタンスフィールドは # names (ハッシュネーム) で宣言され、これは # を先頭にした識別子です。この # は名前の一部で、宣言やアクセスにも使われます。

+ +

このカプセル化は言語によって強制されています。範囲外から # の名前を参照するのは構文エラーです。

+ +
class ClassWithPrivateField {
+  #privateField
+
+  constructor() {
+    this.#privateField = 42
+    this.#randomField = 444 // Syntax error
+  }
+}
+
+const instance = new ClassWithPrivateField()
+instance.#privateField === 42 // Syntax error
+
+ +

プライベートメソッド

+ +

プライベートスタティックメソッド

+ +

プライベートスタティックメソッドは、パブリックと同様に、クラスのインスタンスではなく、クラス自体から呼び出されます。プライベートスタティックフィールドと同様に、クラス宣言の内部からのみアクセス可能です。

+ +

プライベートスタティックメソッドは、ジェネレーター関数、async、非同期ジェネレーター関数、などがあります

+ +
class ClassWithPrivateStaticMethod {
+  static #privateStaticMethod() {
+    return 42
+  }
+
+  static publicStaticMethod1() {
+    return ClassWithPrivateStaticMethod.#privateStaticMethod();
+  }
+
+  static publicStaticMethod2() {
+    return this.#privateStaticMethod();
+  }
+}
+
+console.assert(ClassWithPrivateStaticMethod.publicStaticMethod1() === 42);
+console.assert(ClassWithPrivateStaticMethod.publicStaticMethod2() === 42);
+
+ +

this を使用すると、予期しない動作が発生する可能性があります。次の例では、Derived.publicStaticMethod2() を呼び出そうとしたときに、this派生 クラス(Base クラスではない)を参照しており、上で述べたのと同じ "出自制限" を示します。

+ +
class Base {
+  static #privateStaticMethod() {
+    return 42;
+  }
+  static publicStaticMethod1() {
+    return Base.#privateStaticMethod();
+  }
+  static publicStaticMethod2() {
+    return this.#privateStaticMethod();
+  }
+}
+
+class Derived extends Base {}
+
+console.log(Derived.publicStaticMethod1()); // 42
+console.log(Derived.publicStaticMethod2()); // TypeError
+
+ +

プライベートインスタンスメソッド

+ +

プライベートインスタンスメソッドは、プライベートインスタンスフィールドと同様にアクセスが制限されているクラスインスタンスで利用できるメソッドです。

+ +
class ClassWithPrivateMethod {
+  #privateMethod() {
+    return 'hello world'
+  }
+
+  getPrivateMessage() {
+    return this.#privateMethod()
+  }
+}
+
+const instance = new ClassWithPrivateMethod()
+console.log(instance.getPrivateMessage())
+// expected output: "hello worl​d"
+ +

プライベートインスタンスメソッドは、ジェネレーター関数、async、非同期ジェネレーター関数のいずれかになります。プライベートなゲッターやセッターも可能です。

+ +
class ClassWithPrivateAccessor {
+  #message
+
+  get #decoratedMessage() {
+    return `✨${this.#message}✨`
+  }
+  set #decoratedMessage(msg) {
+    this.#message = msg
+  }
+
+  constructor() {
+    this.#decoratedMessage = 'hello world'
+    console.log(this.#decoratedMessage)
+  }
+}
+
+new ClassWithPrivateAccessor();
+// expected output: "✨hello worl​d✨"
+
+ +

仕様

+ + + + + + + + + + + + +
仕様書
{{SpecName('Public and private instance fields', '#prod-FieldDefinition', 'FieldDefinition')}}
+ +

ブラウザー実装状況

+ + + +

{{Compat("javascript.classes.private_class_fields")}}

+ +

関連情報

+ + -- cgit v1.2.3-54-g00ecf