How to Make Private Properties in JavaScript
The private
keyword in object-oriented languages is an access modifier that can be used to make properties and methods only accessible inside the declared class. This makes it easy to hide underlying logic that should be hidden from curious eyes and should not be interacted with outside from the class.
But how do you achieve the same behavior in JavaScript? There is no reserved keyword for private
. You can simply use it as a variable.
const private = 'private';
Luckily, there are a couple of workarounds you can use to implement private properties and methods in your JavaScript code.
Using Closures
One of the options is to use closures. In short, closures are inner function that has access to outer β enclosing β functionβs variables. Letβs see an example:
(function one() {
var a = 'I\'m available';
// This inner function has access to the outer function scope
(function two() {
console.log(a); // This will log out "I'm available"
})();
})();
This can be translated into assigning the topmost self-invoking function call to a variable, and only exposing some of its inner functions with a function return:
const Button = (function() {
const properties = {
width: 100,
height: 50
};
const getWidth = () => properties.width;
const getHeight = () => properties.height;
const setWidth = width => properties.width = width;
const setHeight = height => properties.height = height;
return function(width, height) {
properties.width = width;
properties.height = height;
return {
getWidth,
getHeight,
setWidth,
setHeight
};
};
})();
This variable will return a function that only returns the set of method
s you want to expose to the outside world. Thereβs no way to directly request or change the properties
. The same can be done with methods. Simply leave out a method from the return
statement to make it private.
Using ES6 Classes
To make your code more similar to the OOP approach, you can use the class
keyword that was introduced in ES6. To make properties and methods private, define them outside of your class. To stay with the example above, this can be rewritten in the following way:
const properties = {
width: 100,
height: 50
};
class Button {
constructor(width, height) {
properties.width = width;
properties.height = height;
}
getWidth = () => properties.width;
getHeight = () => properties.height;
setWidth = width => properties.width = width;
setHeight = height => properties.height = height;
}
Now letβs say your properties are public, but you want to use them in a private
method, where the context is pointing at the Button
. You can achieve it in the following way:
const privates = {
calculateWidth() {
return this.width * this.elements;
}
}
class Button {
constructor(width, height, elements) {
this.width = width;
this.height = height;
this.elements = elements;
}
getWidth = () => privates.calculateWidth.call(this);
getHeight = () => this.height;
setWidth = width => this.width = width;
setHeight = height => this.height = height;
}
Here we are using Function.prototype.call
. It is used for calling a function with a given context. In our case, with the context of the Button
class. If your private function also expects parameters, you can pass them as additional arguments to call
:
// `percent` will equal to 50
calculateWidth(percent) {
return this.width * this.elements * percent;
}
...
privates.calculateWidth.call(this, 50);
Using the Latest ECMAScript Proposal
If youβre reading this article in the future, you may simply be able to use the official way of using private fields. Currently, at the writing of this article, this is at stage 3 proposal. But with the latest version of Babel, you can already use it today. To define private properties or methods, simply prefix it with a hash:
class Button {
// Make properties private
#width
#height
// Make methods private
#calculateWidth() { ... }
#calculateHeight() { ... }
}
Using TypeScript
And of course, mentioning this here as a bonus. You can use TypeScript as a flavor of JavaScript to use the private
keyword to truly recreate the functionality from object-oriented languages.
class Button {
// Make properties private
private width: number;
private height: number;
// Make methods private
private calculateWidth() { ... }
private calculateHeight() { ... }
}
And thatβs all you need to know about privacy in JavaScript. Which approach is your personal favorite? Let us know in the comments below! Thank you for reading through, happy coding!
Rocket Launch Your Career
Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies: