aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/classes/private_class_fields/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/ru/web/javascript/reference/classes/private_class_fields/index.html')
-rw-r--r--files/ru/web/javascript/reference/classes/private_class_fields/index.html206
1 files changed, 206 insertions, 0 deletions
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..86d8220363
--- /dev/null
+++ b/files/ru/web/javascript/reference/classes/private_class_fields/index.html
@@ -0,0 +1,206 @@
+---
+title: Приватные поля класса
+slug: Web/JavaScript/Reference/Classes/Private_class_fields
+translation_of: Web/JavaScript/Reference/Classes/Private_class_fields
+original_slug: Web/JavaScript/Reference/Classes/Приватные_поля_класса
+---
+<div>{{JsSidebar("Classes")}}</div>
+
+<p><span class="seoSummary">Свойства класса по умолчанию являются общедоступными и могут быть рассмотрены или изменены вне класса. Тем не менее, есть <a href="https://github.com/tc39/proposal-class-fields">экспериментальное предложение</a>, позволяющее определить приватные поля класса, используя префикс хэша <code>#</code>.</span></p>
+
+<h2 id="Синтаксис">Синтаксис</h2>
+
+<pre class="syntaxbox notranslate">class ClassWithPrivateField {
+ #privateField
+}
+
+class ClassWithPrivateMethod {
+ #privateMethod() {
+ return 'hello world'
+ }
+}
+
+class ClassWithPrivateStaticField {
+ static #PRIVATE_STATIC_FIELD
+}
+</pre>
+
+<h2 id="Примеры">Примеры</h2>
+
+<h3 id="Приватные_статические_поля">Приватные статические поля</h3>
+
+<p>Приватные поля доступны в конструкторе класса изнутри самой декларации класса.</p>
+
+<p>Ограничение статических переменных, вызываемых только статическими методами, все еще сохраняется.</p>
+
+<pre class="brush: js notranslate">class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+
+  static publicStaticMethod() {
+    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42
+    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD
+  }
+}
+
+console.assert(ClassWithPrivateStaticField.publicStaticMethod() === 42)</pre>
+
+<p>Приватные статические поля добавляются в конструктор класса во время обработки класса.</p>
+
+<p>Существует ограничение по происхождению частных статических полей. Только класс, который определяет приватное статическое поле, может получить доступ к этому полю.</p>
+
+<p>Это может привести к неожиданному поведению при использовании this.</p>
+
+<pre class="brush: js notranslate">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)
+</pre>
+
+<h3 id="Приватные_поля_экземпляров">Приватные поля экземпляров</h3>
+
+<p>Приватные поля экзмепляров объявляются <strong>#имя </strong>(произносится как "хэш нэймс"), которые идентифицируются префиксом <code><strong>#</strong></code>. <code>#</code> является частью имени, а также используется для объявления и доступа.</p>
+
+<p><span class="tlid-translation translation" lang="ru"><span title="">Инкапсуляция обеспечивается языком.</span> <span title="">Обращение к <code>#</code> именам вне области видимости является синтаксической ошибкой.</span></span></p>
+
+<pre class="brush: js notranslate">class ClassWithPrivateField {
+  #privateField
+
+  constructor() {
+    this.#privateField = 42
+    this.#randomField = 666 // Syntax error
+  }
+}
+
+const instance = new ClassWithPrivateField()
+instance.#privateField === 42 // Syntax error
+</pre>
+
+<h3 id="Приватные_методы">Приватные методы</h3>
+
+<h4 id="Приватные_статические_методы">Приватные статические методы</h4>
+
+<p>Приватные статические методы</p>
+
+<p>Как и их публичный эквивалент, приватные статические методы вызываются на самом классе, а не на экземплярах класса. Как и приватные статические поля, они доступны только изнутри объявления класса.</p>
+
+<p>Приватные статические методы могут быть генераторами, асинхронными функциями и асинхронными функциями-генераторами.</p>
+
+<pre class="brush: js notranslate">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);
+</pre>
+
+<p>Это может привести к неожиданному поведению при его использовании <strong><code>this</code></strong>. В следующем примере <code>this</code> относится к классу <code>Derived</code> (а не к классу <code>Base</code>), когда мы пытаемся вызвать <code>Derived.publicStaticMethod2()</code>, и, таким образом, имеет такое же "ограничение по происхождению", как упоминалось выше:</p>
+
+<pre class="brush: js notranslate">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
+</pre>
+
+<h4 id="Приватные_методы_экземпляровinstance">Приватные методы экземпляров(instance)</h4>
+
+<p>Приватные методы экземпляров это методы, доступные у экземпляров класса, доступ к которым запрещен также, как у приватных полей класса.</p>
+
+<pre class="brush: js notranslate">class ClassWithPrivateMethod {
+  #privateMethod() {
+    return 'hello world'
+  }
+
+  getPrivateMessage() {
+      return this.#privateMethod()
+  }
+}
+
+const instance = new ClassWithPrivateMethod()
+console.log(instance.getPrivateMessage())
+// expected output: "hello worl​d"</pre>
+
+<p>Приватные методы экземпляров могут быть генератором, async, или функциями async генератора. Приватные геттеры и сеттеры также возможны:</p>
+
+<pre class="brush: js notranslate">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✨"
+</pre>
+
+<h2 id="Спецификации">Спецификации</h2>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Specification</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{SpecName('Public and private instance fields', '#prod-FieldDefinition', 'FieldDefinition')}}</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2>
+
+<div class="hidden">Таблица совместимости на этой странице составлена из структурированных данных. Если Вы хотите внести свой вклад в данные, пожалуйста, посетите https://github.com/mdn/browser-compat-data и отправьте нам запрос.</div>
+
+<p>{{Compat("javascript.classes.private_class_fields")}}</p>
+
+<h2 id="См._также">См. также</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields">Public class fields</a></li>
+ <li><a href="https://rfrn.org/~shu/2018/05/02/the-semantics-of-all-js-class-elements.html">The Semantics of All JS Class Elements</a></li>
+</ul>