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/public_class_fields/index.html | 350 +++++++++++++++++++++ 1 file changed, 350 insertions(+) create mode 100644 files/ru/web/javascript/reference/classes/public_class_fields/index.html (limited to 'files/ru/web/javascript/reference/classes/public_class_fields') diff --git a/files/ru/web/javascript/reference/classes/public_class_fields/index.html b/files/ru/web/javascript/reference/classes/public_class_fields/index.html new file mode 100644 index 0000000000..ade4b8151f --- /dev/null +++ b/files/ru/web/javascript/reference/classes/public_class_fields/index.html @@ -0,0 +1,350 @@ +--- +title: Поля классов +slug: Web/JavaScript/Reference/Classes/Class_fields +tags: + - JavaScript + - Классы +translation_of: Web/JavaScript/Reference/Classes/Public_class_fields +--- +
{{JsSidebar("Classes")}}
+ +
Объявление публичных и приватных полей является экспериментальной разработкой, предложенной в коммитете стандартов JavaScript TC39. Поддержка браузерами ограничена, но данное нововведение можно использовать посредством транспиляторов (например, Babel). Смотрите информацию о совместимости ниже.
+ +

Публичные поля

+ +

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

+ +

Публичные статические поля

+ +

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

+ +

Публичные статические поля объявляются при помощи ключевого слова static. Они добавляются в конструктор класса во время его создания с помощью Object.defineProperty. Доступ также осуществляется через конструктор класса.

+ +
class ClassWithStaticField {
+  static staticField = 'static field';
+}
+
+console.log(ClassWithStaticField.staticField);
+// Ожидаемый вывод: "static field"
+
+ +

Поля без инициализации имеют значение undefined.

+ +
class ClassWithStaticField {
+  static staticField;
+}
+
+console.assert(ClassWithStaticField.hasOwnProperty('staticField'));
+console.log(ClassWithStaticField.staticField);
+// Ожидаемый вывод: "undefined"
+ +

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

+ +
class ClassWithStaticField {
+  static baseStaticField = 'base field';
+}
+
+class SubClassWithStaticField extends ClassWithStaticField {
+  static subStaticField = 'sub class field';
+}
+
+console.log(SubClassWithStaticField.subStaticField);
+// Ожидаемый вывод: "sub class field"
+
+console.log(SubClassWithStaticField.baseStaticField);
+// Ожидаемый вывод: "base field"
+ +

При определении полей this ссылается на конструктор класса. Также можно обратиться к нему по имени и использовать super для получения конструктора базового класса, если он существует.

+ +
class ClassWithStaticField {
+  static baseStaticField = 'base static field';
+  static anotherBaseStaticField = this.baseStaticField;
+
+  static baseStaticMethod() { return 'base static method output'; }
+}
+
+class SubClassWithStaticField extends ClassWithStaticField {
+  static subStaticField = super.baseStaticMethod();
+}
+
+console.log(ClassWithStaticField.anotherBaseStaticField);
+// Ожидаемый вывод: "base static field"
+
+console.log(SubClassWithStaticField.subStaticField);
+// Ожидаемый вывод: "base static method output"
+
+ +

Публичные поля экземпляра

+ +

Такие публичные поля имеются у каждого экземпляра данного класса. Объявляя публичные поля, мы можем гарантировать, что поле всегда актуально, а объявление класса является более самодокументированным.

+ +

Публичные поля экземпляра добавляются через Object.defineProperty либо перед тем, как будет исполнено тело конструктора в базовом классе, либо после того, как завершится super() в классе наследнике.

+ +
class ClassWithInstanceField {
+  instanceField = 'instance field';
+}
+
+const instance = new ClassWithInstanceField();
+console.log(instance.instanceField);
+// Ожидаемый вывод: "instance field"
+ +

Поля без инициализации имеют значение undefined.

+ +
class ClassWithInstanceField {
+  instanceField;
+}
+
+const instance = new ClassWithInstanceField();
+console.assert(instance.hasOwnProperty('instanceField'));
+console.log(instance.instanceField);
+// Ожидаемый вывод: "undefined"
+ +

Как и свойства, названия полей могут вычисляться.

+ +
const PREFIX = 'prefix';
+
+class ClassWithComputedFieldName {
+    [`${PREFIX}Field`] = 'prefixed field';
+}
+
+const instance = new ClassWithComputedFieldName();
+console.log(instance.prefixField);
+// Ожидаемый вывод: "prefixed field"
+ +

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

+ +
class ClassWithInstanceField {
+  baseInstanceField = 'base field';
+  anotherBaseInstanceField = this.baseInstanceField;
+  baseInstanceMethod() { return 'base method output'; }
+}
+
+class SubClassWithInstanceField extends ClassWithInstanceField {
+  subInstanceField = super.baseInstanceMethod();
+}
+
+const base = new ClassWithInstanceField();
+const sub = new SubClassWithInstanceField();
+
+console.log(base.anotherBaseInstanceField);
+// Ожидаемый вывод: "base field"
+
+console.log(sub.subInstanceField);
+// Ожидаемый вывод: "base method output"
+ +

Публичные методы

+ +

Публичные статические методы

+ +

Ключевое слово static объявляет статический метод класса. Статические методы не вызываются из экземпляра, вместо этого они вызывается из самого класса. Чаще всего это какие-либо служебные функции, такие как функции создания или копирования объектов.

+ +

{{EmbedInteractiveExample("pages/js/classes-static.html")}}

+ + + +

Статические методы добавляются в конструктор класса с помощью Object.defineProperty во время его создания. Эти методы - изменяемые, неперечисляемые и настраеваемые свойства объекта.

+ +

Публичные методы экземпляра

+ +

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

+ +
class ClassWithPublicInstanceMethod {
+  publicMethod() {
+    return 'hello world';
+  }
+}
+
+const instance = new ClassWithPublicInstanceMethod();
+console.log(instance.publicMethod());
+// Ожидаемый вывод: "hello worl​d"
+ +

Публичные методы добавляются в прототип класса во время его создания с помощью Object.defineProperty. Они изменяемы, неперечисляемы и настраиваемы.

+ +

Вы можете использовать генераторы, асинхронные функции и асинхронные генераторы.

+ +
class ClassWithFancyMethods {
+  *generatorMethod() { }
+  async asyncMethod() { }
+  async *asyncGeneratorMethod() { }
+}
+ +

Внутри методов экземпляра, this ссылается на сам экземпляр.
+ В классах наследниках, super дает доступ к прототипу базового класса, позволяя вызывать его методы.

+ +
class BaseClass {
+  msg = 'hello world';
+  basePublicMethod() {
+    return this.msg;
+  }
+}
+
+class SubClass extends BaseClass {
+  subPublicMethod() {
+    return super.basePublicMethod();
+  }
+}
+
+const instance = new SubClass();
+console.log(instance.subPublicMethod());
+// Ожидаемый вывод: "hello worl​d"
+
+ +

Геттеры и сеттеры это специальные методы, которые привязаны к свойствам класса и которые вызываются, когда к свойсту обращаются или записывают. Используйте get и set для объявления публичных геттеров и сеттеров экземпляра.

+ +
class ClassWithGetSet {
+  #msg = 'hello world';
+  get msg() {
+    return this.#msg;
+  }
+  set msg(x) {
+    this.#msg = `hello ${x}`;
+  }
+}
+
+const instance = new ClassWithGetSet();
+console.log(instance.msg);
+// Ожидаемый вывод: "hello worl​d"
+
+instance.msg = 'cake';
+console.log(instance.msg);
+// Ожидаемый вывод: "hello cake"
+
+ +

Приватные поля

+ +

Приватные статические поля

+ +

Приватные поля доступны через конструктор внутри объявления самого класса.

+ +

Также сохраняется ограничение на вызов статических полей только внутри статических методов.

+ +
class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD;
+
+  static publicStaticMethod() {
+    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42;
+    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD;
+  }
+}
+
+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 { }
+
+assertThrows(() => SubClass.basePublicStaticMethod(), TypeError);
+
+ +

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

+ +

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

+ +

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

+ +
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 publicStaticMethod() {
+        return ClassWithPrivateStaticMethod.#privateStaticMethod();
+    }
+}
+
+assert(ClassWithPrivateStaticField.publicStaticMethod() === 42);
+
+ +

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

+ +

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

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

Приватные методы экземпляра объекта могут быть генераторами, асинхронными функциями и асинхронными генераторами. Также возможны приватные геттеры и сеттеры:

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

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

+ +

Публичные поля класса

+ + + +

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

+ +

Приватные поля класса

+ + + +

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

+ +

Смотрите также

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