Private and protected properties and methods

8 minutes read

Private and protected properties and methods in JavaScript provide a way to control access to the internal state and behavior of an object. They help encapsulate the implementation details and expose only the necessary interfaces to the outside world. In this topic, you will learn about them. Let's start with the private properties first.

Private Properties

Private properties in JavaScript are a way to encapsulate data within an object, making it inaccessible from outside the object. Private properties ensure data privacy and abstraction, allowing you to hide implementation details and expose only the necessary functionality to the outside world.

With the release of ECMAScript 2015 (ES6), JavaScript introduced a new syntax for creating private properties using the concept of WeakMap. WeakMap is a built-in JavaScript object that allows you to associate private data with a specific object.

Here's an example that demonstrates how to use private properties in JavaScript:

const privateData = new WeakMap();

class MyClass {
  constructor() {
    privateData.set(this, { privateProperty: 'I am private!' });
  }

  getPrivateProperty() {
    return privateData.get(this).privateProperty;
  }

  setPrivateProperty(value) {
    privateData.get(this).privateProperty = value;
  }
}

const myObject = new MyClass();
console.log(myObject.getPrivateProperty()); // Output: 'I am private!'
myObject.setPrivateProperty('New value');
console.log(myObject.getPrivateProperty()); // Output: 'New value'

Let's break down the code from above.

First, we created a new instance of the WeakMap object that allows us to associate key-value pairs. Inside the MyClass class, we use privateData to store private properties associated with each instance of the class. privateProperty is stored as a key-value pair within the privateData map.

The getPrivateProperty() method allows us to access private property, and the setPrivateProperty() method lets us modify its value.

Since the privateData map is created outside the class, it is not accessible from outside the class. Hence, the private property remains hidden and cannot be accessed directly by external code.

It's important to note that private properties are not truly secure or protected in JavaScript. They provide a level of encapsulation but can still be accessed or modified using techniques like reflection or monkey-patching. However, private properties discourage direct access and signal that they should not be accessed externally, helping to maintain the integrity and intended usage of an object's internals.

Protected Properties

In JavaScript, there is no concept of "protected properties" like in some other object-oriented programming languages, such as Java or C++. However, you can achieve a similar level of encapsulation and access control by using naming conventions and closures.

In JavaScript, properties and methods can be declared public or private, but there is no built-in mechanism to declare them as "protected." Public properties and methods can be accessed and modified from anywhere, while private properties and methods are only accessible within the same scope or closure.

To emulate the behavior of protected properties, a common convention is to prefix the property name with a hash (#). This indicates that the property should be considered private, even though it can still be accessed from outside the object. It serves as a naming convention to signal that the property is intended for internal use and should be treated as "protected." Let's look at an example of protected properties:

function MyClass() {
  var #protectedProperty = 42;

  this.publicProperty = 'Hello';

  this.getProtectedProperty = function() {
    return #protectedProperty;
  };

  this.setProtectedProperty = function(value) {
    #protectedProperty = value;
  };
}

var myObject = new MyClass();

console.log(myObject.publicProperty);  // Output: Hello
console.log(myObject.getProtectedProperty());  // Output: 42

myObject.setProtectedProperty(24);
console.log(myObject.getProtectedProperty());  // Output: 24

The variable named #protectedProperty is assigned the value 42. This variable is intended to be private property because it is declared using the var keyword inside the constructor function, making it inaccessible outside the class.

The class also has a public property publicProperty, which is assigned the value 'Hello'. This property can be accessed directly from outside the class.

To provide access to private property, the class defines two methods: getProtectedProperty and setProtectedProperty. The getProtectedProperty method returns the value of the private property and the setProtectedProperty method allows modifying the private property by accepting a new value.

Private methods

In JavaScript, there is no native support for private methods. Instead, there are certain techniques and conventions you can use to achieve similar behavior and encapsulation. By prefixing a method with a hash (#), you can signal to other developers that the method is intended to be private and should not be accessed from outside the object. Here is an example of private methods:

class ParentClass {
  #privateMethod() {
    console.log('This is a private method');
  }
}

class ChildClass extends ParentClass {
  callPrivateMethod() {
    this.#privateMethod(); // Error: Private method '#privateMethod' is not accessible outside of class 'ParentClass'
  }
}

const childInstance = new ChildClass();
childInstance.callPrivateMethod(); // Error: Private method '#privateMethod' is not accessible outside of class 'ParentClass'

In this example, ParentClass defines a private method #privateMethod(). ChildClass extends ParentClass but is unable to access the private method directly. Attempting to call the private method #privateMethod() in callPrivateMethod() will result in an error.

Private methods are denoted by the # prefix in their names. They can only be accessed within the class that defines them and are not accessible in subclasses or from external code.

Protected methods

There is no native access modifier like "protected" that restricts the visibility of methods or properties within a class hierarchy. You can still achieve a similar effect of protected methods in JavaScript by using naming conventions and documentation to indicate that certain methods or properties should be treated as "protected" and not accessed directly from outside the class or its subclasses. By convention, developers may choose to use an underscore prefix (_) to indicate that a method or property is intended for internal use or should be treated as protected. Here is an example of a protected method in JavaScript:

class ParentClass {
  _protectedMethod() {
    console.log('This is a protected method');
  }
}

class ChildClass extends ParentClass {
  callProtectedMethod() {
    this._protectedMethod();
  }
}

const childInstance = new ChildClass();
childInstance.callProtectedMethod();

In this example, ParentClass defines a protected method _protectedMethod(). ChildClass extends ParentClass and has access to the protected method. The callProtectedMethod() method in ChildClass calls the _protectedMethod() method inherited from ParentClass.

Conclusion

To summarize, JavaScript does not have built-in support for private and protected properties and methods like some other object-oriented programming languages. However, developers can emulate them. By prefixing property names with an underscore, developers can signal that they should be treated as "protected" and accessed with caution. Private and protected methods can also be simulated using similar conventions, where private methods are indicated by an underscore prefix and protected methods are defined within the scope of the object.

12 learners liked this piece of theory. 2 didn't like it. What about you?
Report a typo