From c058fa0fb22dc40ef0225b21a97578cddd0aaffa Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 14:51:05 +0100 Subject: unslug ru: move --- .../classes/private_class_fields/index.html | 205 +++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 files/ru/web/javascript/reference/classes/private_class_fields/index.html (limited to 'files/ru/web/javascript/reference/classes/private_class_fields/index.html') diff --git a/files/ru/web/javascript/reference/classes/private_class_fields/index.html b/files/ru/web/javascript/reference/classes/private_class_fields/index.html new file mode 100644 index 0000000000..09fe2505e2 --- /dev/null +++ b/files/ru/web/javascript/reference/classes/private_class_fields/index.html @@ -0,0 +1,205 @@ +--- +title: Приватные поля класса +slug: Web/JavaScript/Reference/Classes/Приватные_поля_класса +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)
+
+ +

Приватные поля экземпляров

+ +

Приватные поля экзмепляров объявляются #имя (произносится как "хэш нэймс"), которые идентифицируются префиксом #. # является частью имени, а также используется для объявления и доступа.

+ +

Инкапсуляция обеспечивается языком. Обращение к # именам вне области видимости является синтаксической ошибкой.

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

Приватные методы

+ +

Приватные статические методы

+ +

Приватные статические методы

+ +

Как и их публичный эквивалент, приватные статические методы вызываются на самом классе, а не на экземплярах класса. Как и приватные статические поля, они доступны только изнутри объявления класса.

+ +

Приватные статические методы могут быть генераторами, асинхронными функциями и асинхронными функциями-генераторами.

+ +
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. В следующем примере this относится к классу Derived (а не к классу Base), когда мы пытаемся вызвать Derived.publicStaticMethod2(), и, таким образом, имеет такое же "ограничение по происхождению", как упоминалось выше:

+ +
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
+
+ +

Приватные методы экземпляров(instance)

+ +

Приватные методы экземпляров это методы, доступные у экземпляров класса, доступ к которым запрещен также, как у приватных полей класса.

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

Приватные методы экземпляров могут быть генератором, async, или функциями 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✨"
+
+ +

Спецификации

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

Совместимость с браузерами

+ + + +

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

+ +

См. также

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