How to Make Private Properties in JavaScript

How to Make Private Properties in JavaScript

Looking at various ways to prevent exposing your methods
Ferenc Almasi β€’ Last updated 2021 November 11 β€’ Read time 5 min read
Get your weekly dose of webtips
  • twitter
  • facebook
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.

Copied to clipboard!
const private = 'private';
private.js
private is not a reserved keyword, I can set it to anything.

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:

Copied to clipboard! Playground
(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"
    })();
})();
closure.js

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:

Copied to clipboard! Playground
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
        };
    };
})();
closure.js

This variable will return a function that only returns the set of methods 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.

Logging available methods and properties to Chrome DevTools
Only the returned methods are available. Properties are kept 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:

Copied to clipboard! Playground
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;
}
classes.js

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:

Copied to clipboard! Playground
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;
}
classes.js

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:

Copied to clipboard! Playground
// `percent` will equal to 50
calculateWidth(percent) {
    return this.width * this.elements * percent;
}

...
privates.calculateWidth.call(this, 50);
classes.js
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScriptinfo Remove ads

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:

Copied to clipboard! Playground
class Button {
    // Make properties private
    #width
    #height

    // Make methods private
    #calculateWidth()  { ... }
    #calculateHeight() { ... }
}
private.js
Babel transpiles it down to WeakMaps and WeakSets

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.

Copied to clipboard! Playground
class Button {
    // Make properties private
    private width: number;
    private height: number;

    // Make methods private
    private calculateWidth()  { ... }
    private calculateHeight() { ... }
}
typescript.ts
TypeScript 3.8 also supports the new JavaScript syntax for private fields

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!

  • twitter
  • facebook
JavaScript
Did you find this page helpful?
πŸ“š More Webtips
Mentoring

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:

Courses

Recommended

This site uses cookies We use cookies to understand visitors and create a better experience for you. By clicking on "Accept", you accept its use. To find out more, please see our privacy policy.