Defining Instance and Static Fields in JavaScript
Modern JavaScript introduces class field declaration syntax, allowing
developers to define properties directly within the class body without
requiring explicit assignment inside the constructor. This
syntax standardizes how both instance members (belonging to each object
instance) and static members (belonging to the class constructor itself)
are created. By supporting both public and private visibility, class
fields provide a cleaner, more declarative way to structure state in
object-oriented JavaScript.
Instance Fields
Instance fields represent properties that are created and maintained separately on each instantiated object.
Public Instance Fields
Public instance fields are declared directly in the class body with an optional initializer:
class User {
role = 'guest'; // Public instance field
constructor(name) {
this.name = name;
}
}
const user1 = new User('Alice');
console.log(user1.role); // "guest"When an instance is created, public instance fields are initialized
automatically. In a derived class (using extends), these
fields are set immediately after super() returns.
Private Instance Fields
Private instance fields are declared using a hash #
prefix. These fields cannot be accessed, modified, or detected from
outside the class lexical scope:
class BankAccount {
#balance = 0; // Private instance field
deposit(amount) {
this.#balance += amount;
}
getBalance() {
return this.#balance;
}
}
const account = new BankAccount();
account.deposit(100);
console.log(account.getBalance()); // 100
// console.log(account.#balance); // SyntaxError: Private field '#balance' must be declared in an enclosing classStatic Fields
Static fields belong to the class function itself rather than to instances of the class. They are shared across the application and are commonly used for caching, fixed configuration, or factory helpers.
Public Static Fields
Public static fields are declared by prefixing the field name with
the static keyword:
class Configuration {
static defaultTimeout = 5000; // Public static field
}
console.log(Configuration.defaultTimeout); // 5000
const config = new Configuration();
console.log(config.defaultTimeout); // undefinedPublic static fields are attached directly to the constructor function at the time the class definition is evaluated.
Private Static Fields
Private static fields combine the static keyword with
the # prefix. They are accessible only by methods defined
within the class:
class Counter {
static #count = 0; // Private static field
constructor() {
Counter.#count++;
}
static getCount() {
return Counter.#count;
}
}
new Counter();
new Counter();
console.log(Counter.getCount()); // 2
// console.log(Counter.#count); // SyntaxErrorKey Differences and Initialization Order
- Evaluation Timing: Static fields are initialized
once, when the class definition is executed by the JavaScript engine.
Instance fields are evaluated and assigned every time a new instance is
created via the
newkeyword. - Access Scope: Instance fields are accessed via
instance references (
this.fieldorinstance.field), whereas static fields are accessed via the class constructor (Class.field) or within the class definition. - Encapsulation: Using the
#identifier enforces hard privacy at the language level for both instance and static members, preventing direct external access through reflection or property inspection.