--- 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">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">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">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">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">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">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">class ClassWithPrivateMethod { #privateMethod() { return 'hello world' } getPrivateMessage() { return this.#privateMethod() } } const instance = new ClassWithPrivateMethod() console.log(instance.getPrivateMessage()) // expected output: "hello world"</pre> <p>Приватные методы экземпляров могут быть генератором, async, или функциями async генератора. Приватные геттеры и сеттеры также возможны:</p> <pre class="brush: js">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 world✨" </pre> <h2 id="Спецификации">Спецификации</h2> <p>{{Specifications("javascript.classes")}}</p> <h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> <p>{{Compat("javascript.classes")}}</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>