---
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 worl​d"</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 worl​d✨"
</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>