How to define a private field in JavaScript Classes?

With the recent advancements in JavaScript with ES2022, classes can now have private fields which are accessible only thorough class object for modification.
To define a private field we prefix the field name with # sign.

Let’s define a class for Square which has length as private field as each object should hold unique data and access should be restricted for modification from outside.

class Square {
  // defining private field using # symbol
  #length;
  constructor(value) {
    this.#length = value;
  }
  get area() {
    return this.#length * this.#length;
  }
}

Explanation:
We have defined a private field length initialized using constructor where passed value is set to length and then a method to calculate the area of square and return the result.
Access to length is restricted to the class only, cannot be accessed outside.

let square = new Square(50);
// accessing 
console.log(square.area); // output: 2500

Explanation:
Initializing an object named square and passing value for length in constructor and logging out the result using method.

Accessing private fields using getter and setter methods

Private fields can be accessed only inside a object so how can I set values apart from constructor.
We can define methods to get and set values to private fields as this will save us from setting wrong values directly as these functions can also define rules for setting values like, values should not be null or values should be greater than a certain values like length > 0.
These validations help keep control on values getting set to variables.

class Square {
  #length = 0;
  constructor(value) {
    this.#length = value; // setting value during object initialization
  }
  get area() {
    return this.#length * this.#length;
  }
  set setLength(value) {
    if (typeof value === 'number' && value > 0) {
      this.#length = value;
    } else {
      throw 'length must be a greater than 0';
    }
  }
  get getLength() {
    return this.#length;
  }
}

Explanation:
Defined a class Square with length field and two methods.
getLength() to access the private field length.
setLength() to set values to private field length with validation for correct type and value.
It’s a good practice to include get and set in the function name for better code readability.

Subclasses and private fields access control

When we extend a class from base class the private fields are NOT accessible inside the subclass, i.e. private fields are only accessible inside the class they are defined.

Lets define a class Cube with private field height for calculating area of a cube.
Cube class will extend the Square class and try accessing private variable length from Square class inside Cube class.

class Cube extends Square {
  //private field height for Cube class
  #height;
  constructor(length, height) {
    // trying to set length field from Square class
    super(length);
    this.#height = height;

    // we cannot access the #length of the Square class 
    // trying this will create a SytaxError : can't access private field
  }
}

Defining static private fields inside class

Static fields helps in maintaining a single copy of the field inside multiple instances of the object.
Even if we create 100 object of class that has a static field, there will be only one copy of the field memory so any updates on object will result in same value getting updates which means each object will get the new value after update.

class SampleStaticPrivateField {
  static #staticField = 0;
  get getStaticField() {
    return this.#staticField;
  }
  set setStaticField(value) {
    this.#staticField = value;
  }
}

// creating 3 different objects of same class
let objectOne = new SampleStaticPrivateField();
let objectTwo = new SampleStaticPrivateField();
let objectThree = new SampleStaticPrivateField();

console.log(objectOne.getStaticField()); // output : 0
console.log(objectTwo.getStaticField()); // output : 0
console.log(objectThree.getStaticField()); // output : 0

// update value in only object
objectTow.setStaticField(2);

// printing values and output is same but value was updated only in one object
console.log(objectOne.getStaticField()); // output : 2
console.log(objectTwo.getStaticField()); // output : 2
console.log(objectThree.getStaticField()); // output : 2

Explanation:
If we look at the console.log() output we can clearly see that the values are same for all objects because the static keyword creates a link to all objects to access same memory space allocated in JavaScript heap memory so any update by other objects results in same memory to get updates which is accessed by all objects because of which we receive same values in output after updating value.

Checking if private field exists using in operator

The private variable is not accessible outside of class so how can we validate if the fields exist?
We need to create a method to validate the private field and access it accordingly using object.
The in operator returns a Boolean value either true or false

// Syntax : <field name> in <class name>

class ValidatePrivateFieldExists {
  static #staticField = 0;
  get checkFieldExists() {
    return #staticField in ValidatePrivateFieldExists ;
  }
}
let validatePrivateField = new ValidatePrivateFieldExists();
console.log(validatePrivateField.checkFieldExists()) // output: true
Scroll to Top