Приватные поля класса
Свойства класса по умолчанию являются общедоступными и могут быть рассмотрены или изменены вне класса. Тем не менее, есть экспериментальное предложение, позволяющее определить приватные поля класса, используя префикс хэша #
.
Синтаксис
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 world"
Приватные методы экземпляров могут быть генератором, 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 world✨"
Спецификации
Specification |
---|
ECMAScript Language Specification # sec-class-definitions |
Совместимость с браузерами
javascript.classes.private_class_fields
BCD tables only load in the browser
javascript.classes.private_class_fields_in
BCD tables only load in the browser
javascript.classes.private_class_methods
BCD tables only load in the browser