Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

Private fields are class properties prefixed with a hash (#) that enforce strict encapsulation at the language level. Unlike the traditional underscore convention (_property), private fields provide “hard privacy”—they are completely inaccessible and invisible outside the lexical scope of the class body in which they are defined.

Syntax and Declaration

Private fields must be explicitly declared in the class body before they can be accessed or mutated. They cannot be dynamically added to an instance at runtime.
class Container {
  // Mandatory upfront declaration
  #internalState;
  #initializedState = 100;

  constructor(value) {
    // Access via 'this.#fieldName'
    this.#internalState = value;
  }

  readState() {
    return this.#internalState + this.#initializedState;
  }
}

const instance = new Container(50);
console.log(instance.readState()); // 150

Core Mechanics and Rules

1. Strict Lexical Scoping Accessing a private field outside of its defining class results in a SyntaxError. This is evaluated at compile-time, preventing execution entirely.
const instance = new Container(50);
console.log(instance.#internalState); // SyntaxError: Private field '#internalState' must be declared in an enclosing class
2. Bracket Notation Incompatibility Private fields cannot be accessed using bracket notation. Attempting to do so will interact with a public string property that happens to start with a hash, rather than the actual private field.
class BracketTest {
  #secret = 'hidden';
  
  constructor() {
    this['#secret'] = 'public'; 
  }

  getSecret() {
    return this.#secret; // Returns 'hidden'
  }
}
3. Inheritance Restrictions Private fields are bound strictly to the class that defines them. Subclasses cannot access the private fields of their parent classes.
class Parent {
  #parentData = 'data';
}

class Child extends Parent {
  accessParent() {
    return this.#parentData; // SyntaxError
  }
}

Static Private Fields and Methods

The # prefix can also be applied to static properties and class methods (both instance and static). Static private fields are evaluated on the class constructor itself rather than the instance.
class Utility {
  static #cache = new Map();

  static #compute(key) {
    return key * 2;
  }

  static process(key) {
    if (!this.#cache.has(key)) {
      this.#cache.set(key, this.#compute(key));
    }
    return this.#cache.get(key);
  }
}

Ergonomic Brand Checks

JavaScript provides a mechanism to safely check if an object possesses a specific private field using the in operator. This is known as a “brand check” and will not throw an error if the field is missing, returning a boolean instead.
class Node {
  #value;

  constructor(value) {
    this.#value = value;
  }

  static isNode(obj) {
    // Evaluates to true if 'obj' has the '#value' private field
    return #value in obj;
  }
}

const validNode = new Node(1);
const fakeNode = { value: 1 };

console.log(Node.isNode(validNode)); // true
console.log(Node.isNode(fakeNode));  // false
Master JavaScript with Deep Grasping Methodology!Learn More