Get to know MDN better
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2022.
Public fields are writable, enumerable, and configurable properties defined on each class instance or class constructor.
There are some additional syntax restrictions:
This page introduces public instance fields in detail.
Public instance fields exist on every created instance of a class. By declaring a public field, you can ensure the field is always present, and the class definition is more self-documenting.
Public instance fields are added to the instance either at construction time in the base class (before the constructor body runs), or just after super() returns in a subclass. Fields without initializers are initialized to undefined. Like properties, field names may be computed.
Computed field names are only evaluated once, at class definition time. This means that each class always has a fixed set of field names, and two instances cannot have different field names via computed names. The this value in the computed expression is the this surrounding the class definition, and referring to the class's name is a ReferenceError because the class is not initialized yet. await and yield work as expected in this expression.
In the field initializer, this refers to the class instance under construction, and super refers to the prototype property of the base class, which contains the base class's instance methods, but not its instance fields.
The field initializer expression is evaluated each time a new instance is created. (Because the this value is different for each instance, the initializer expression can access instance-specific properties.)
The expression is evaluated synchronously. You cannot use await or yield in the initializer expression. (Think of the initializer expression as being implicitly wrapped in a function.)
Because instance fields of a class are added before the respective constructor runs, you can access the fields' values within the constructor. However, because instance fields of a derived class are defined after super() returns, the base class's constructor does not have access to the derived class's fields.
Fields are added one-by-one. Field initializers can refer to field values above it, but not below it. All instance and static methods are added beforehand and can be accessed, although calling them may not behave as expected if they refer to fields below the one being initialized.
Note: This is more important with private fields, because accessing a non-initialized private field throws a TypeError, even if the private field is declared below. (If the private field is not declared, it would be an early SyntaxError.)
Because class fields are added using the [[DefineOwnProperty]] semantic (which is essentially Object.defineProperty()), field declarations in derived classes do not invoke setters in the base class. This behavior differs from using this.field = … in the constructor.
Note: Before the class fields specification was finalized with the [[DefineOwnProperty]] semantic, most transpilers, including Babel and tsc, transformed class fields to the DerivedWithConstructor form, which has caused subtle bugs after class fields were standardized.
Class fields cannot depend on arguments of the constructor, so field initializers usually evaluate to the same value for each instance (unless the same expression can evaluate to different values each time, such as Math.random() or object initializers).
However, even declaring an empty class field is beneficial, because it indicates the existence of the field, which allows type checkers as well as human readers to statically analyze the shape of the class.
The code above seems repetitive, but consider the case where this is dynamically mutated: the explicit field declaration makes it clear which fields will definitely be present on the instance.
Because initializers are evaluated after the base class has executed, you can access properties created by the base class constructor.
| ECMAScript® 2027 Language Specification # prod-FieldDefinition |
Enable JavaScript to view this browser compatibility table.
This page was last modified on Jul 8, 2025 by MDN contributors.
Your blueprint for a better internet.
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998–2026 by individual mozilla.org contributors. Content available under a Creative Commons license.