Private Fields in JavaScript

Private Fields in JavaScript

In this post, we are going to learn about private fields in JavaScript.

Before we start, I will like to apologise for not having updated my blog in such a long time. I have been absorbed with building my personal projects and learning. I also had to deal with school (and still have to) but I am trying to get back at creating content on both my Twitter account and my blog. In order to not miss anything, make sure to follow me on Twitter here

Now let us begin.

What are private fields (and public fields) ?

To get an idea of what that is, think abstraction. Let us take the example of a car. When we buy a car, we don't know everything about the car right ? All we know is that this is a vehicle of brand Tesla, for example and that it has 4 tires. You can think of the terms in italic as public details of the vehicle. These details are public to any individual that sees your car. Unless you work at Tesla, you won't know about the internal workings of the car. As a result, those other details hidden to us are considered private.

Now you should get an idea of what public and private fields are in general, this does not only apply in JavaScript.

In JavaScript, fields are public by default, which means that anyone can access it. Let us define a class called Vehicle in which we will experiment with public and private fields.

Let us define that class and set some fields.

class Vehicle {
  constructor(vehicleType, vehicleBrand, wheelCount) {
    this.vehicleType = vehicleType;
    this.vehicleBrand = vehicleBrand;
    this.wheelCount = wheelCount;
  }
  getWheelCount() {
    return this.wheelCount;
  }
}

In the class above, the fields vehicleType, vehicleBrand and wheelCount are considered public fields. If we instantiate our class, then we would be able to access the variable mentioned above very easily.

const myTesla = new Vehicle("car", "Tesla", 4);

console.log(myTesla.vehicleType);
console.log(myTesla.vehicleBrand);
console.log(myTesla.wheelCount);
console.log("Wheel Count : ", myTesla.getWheelCount());

If you run the code above, we would be able to get the value of the class fields and execute the getWheelCount() method without any issues.

Now let's see how we can define private fields or make methods private.

Let's update our class and add some private fields. In order to make a field private, all we have to do is add a # before the field name like #fieldName.

Update the class code to look like the one below.

class Vehicle {
  #engineType; // Thermal, Electrical
  constructor(vehicleType, vehicleBrand, wheelCount, engineType) {
    this.vehicleType = vehicleType;
    this.vehicleBrand = vehicleBrand;
    this.wheelCount = wheelCount;
    this.#engineType = engineType;
  }
  getWheelCount() {
    return this.wheelCount;
  }
}

In the code above, we have defined a private field in our class called engineType. This field is accessible only within the class and therefore cannot be accessed from outside. When dealing with private field values, we must always add the # prefix to its name so that we know we are accessing a private field.

Now update the code were we instantiated our class to look like below;

console.log(myTesla.vehicleType);
console.log(myTesla.vehicleBrand);
console.log(myTesla.wheelCount);
console.log("Wheel Count : ", myTesla.getWheelCount());
console.log(myTesla.engineType);

If we instantiate the class once more and try to access the private field from outside, we get undefined as result. And if we add, the # like below;

console.log(myTesla.#engineType);

we will get a syntax error.

This is a proof that this field has effectively been made private in our class. In order to make a method private too, we will add the # prefix to the method name,

class Vehicle {
  #engineType; // Thermal, Electrical
  constructor(vehicleType, vehicleBrand, wheelCount, engineType) {
    this.vehicleType = vehicleType;
    this.vehicleBrand = vehicleBrand;
    this.wheelCount = wheelCount;
    this.#engineType = engineType;
  }
  getWheelCount() {
    return this.wheelCount;
  }

  #getEngineType() {
    return this.#engineType;
  }

  whichEngine() {
    return this.#getEngineType();
  }
}

In the code above, I have defined a private method called getEngineType. We cannot access this method out of the class. For this reason, we could have another method execute this function and return to us the engine type of the car. Consider the whichEngine() method to be the technical support from the car manufacturing. We would not get the engine type of our car except from them and so we contact them using the whichEngine() method.

In the end, we can now update the code with our own Tesla object to look like this;

const myTesla = new Vehicle("car", "Tesla", 4, "Electric");

console.log(myTesla.vehicleType);
console.log(myTesla.vehicleBrand);
console.log(myTesla.wheelCount);
console.log(myTesla.whichEngine());
console.log("Wheel Count : ", myTesla.getWheelCount());

This will be the end for this blog post. I hope you learned something from here.

If you want to learn more about private fields, consider looking into the MDN docs

Have a nice day ;)