Private fields include private instance fields and private static fields.
Private instance fields
Private instance fields are declared with # names (pronounced "hash names"), which are identifiers prefixed with #
. The #
is a part of the name itself. Private fields are accessible on the class constructor from inside the class declaration itself. They are used for declaration of field names as well as for accessing a field's value.
It is a syntax error to refer to #
names from out of scope. It is also a syntax error to refer to private fields that were not declared before they were called, or to attempt to remove declared fields with delete
.
class ClassWithPrivateField {
#privateField;
constructor() {
this.#privateField = 42;
delete this.#privateField;
this.#undeclaredField = 444;
}
}
const instance = new ClassWithPrivateField()
instance.#privateField === 42;
Note: Use the in
operator to check for potentially missing private fields (or private methods). This will return true
if the private field or method exists, and false
otherwise.
Like public fields, private fields are added at construction time in a base class, or at the point where super()
is invoked in a subclass.
class ClassWithPrivateField {
#privateField;
constructor() {
this.#privateField = 42;
}
}
class SubClass extends ClassWithPrivateField {
#subPrivateField;
constructor() {
super();
this.#subPrivateField = 23;
}
}
new SubClass();
Note: #privateField
from the ClassWithPrivateField
base class is private to ClassWithPrivateField
and is not accessible from the derived Subclass
.
Private static fields
Private static fields are added to the class constructor at class evaluation time. Like their public counterparts, private static fields are only accessible on the class itself or on the this
context of static methods, but not on the this
context of instance methods.
class ClassWithPrivateStaticField {
static #PRIVATE_STATIC_FIELD;
static publicStaticMethod() {
ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42;
return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD;
}
publicInstanceMethod() {
ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42;
return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD;
}
}
console.log(ClassWithPrivateStaticField.publicStaticMethod());
console.log(new ClassWithPrivateStaticField().publicInstanceMethod());
There is a restriction on private static fields: Only the class which defines the private static field can access the field. This can lead to unexpected behavior when using this
. In the following example, this
refers to the SubClass
class (not the BaseClassWithPrivateStaticField
class) when we try to call SubClass.basePublicStaticMethod()
, and so causes a TypeError
.
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.log(error instanceof TypeError);
console.log(error);