Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to work with private variables in ES6? [duplicate]

In ES5, you could emulate a class with private and public variables like this:

car.js

function Car() {
    // using var causes speed to be only available inside Car (private)
    var speed = 10;

    // public variable - still accessible outside Car
    this.model = "Batmobile";

    // public method
    this.init = function(){

    }
}

But in ES6, you can no longer declare vars outside the constructor, making it actually HARDER to work with classes in a OOP way!?

You can declare variables in the constructor using this, but that makes them public by default. This is very weird since ES6 DOES have a get / set keyword!

class Vehicle {
    constructor(make, year) {
        // the underscore is nice, but these are still public!
        this._make = make;
        this._year = year;
    }

    // get and set can be handy, but would make more sense
    // if _make and _year were not accessible any other way!
    get make() {
        return this._make;
    }

    get year() {
        return this._year;
    }
}
like image 937
Kokodoko Avatar asked Dec 22 '15 14:12

Kokodoko


People also ask

How you make private property in #JavaScript object literal?

You also can add closures as members, so create private fields which are method private rather than object private. dataset = { secretCounter: ( function () { var c = 0; return function () { return ++c; } })(), ... So dataset. secretCounter() has a varable c which is private to that function only.

Can I use private class fields?

Private fields are accessible on the class constructor from inside the class declaration itself. They are used for declaration of field names as well as for accessing a field's value.

How do you make a property method private in ES6?

Short answer, no, there is no native support for private properties with ES6 classes. But you could mimic that behaviour by not attaching the new properties to the object, but keeping them inside a class constructor, and use getters and setters to reach the hidden properties.

How do you define a private method or variable inside a class in JavaScript or ES6?

To make a public method private, you prefix its name with a hash # . JavaScript allows you to define private methods for instance methods, static methods, and getter/setters. The following shows the syntax of defining a private instance method: class MyClass { #privateMethod() { //... } }


2 Answers

ES6 standard does not offer a new way for defining private variables.

It's a fact, that new ES6 class is simply syntactic sugar around regular prototype-based constructors.

get and set keywords are offering a way for simplified definition of ES5 custom getters and setters that were previously defined with a descriptor of Object.defineProperty()

The best you could do is to use those techniques with Symbols or WeakMaps

The example below features the use of a WeakMap for storing private properties.

// myModule.js
const first_name = new WeakMap();

class myClass {
     constructor (firstName) {
          first_name.set(this, firstName);
     }

     get name() {
          return first_name.get(this);
     }
}

export default myClass;

I'm referring to article, written by David Vujic What? Wait. Really? Oh no! (a post about ES6 classes and privacy) with the idea of using WeakMaps.

like image 82
halfzebra Avatar answered Sep 22 '22 03:09

halfzebra


The same way than in ES5: define the methods that must access the private variables in the constructor instead of the prototype, thus making them privileged methods.

Otherwise there in no good way to allow prototypical methods to access private data, but still hide it from the outside. You can try symbols, weakmaps or handshakes, but IMO none is perfect. See accessing private member variables from prototype-defined functions for some ideas.

like image 32
Oriol Avatar answered Sep 22 '22 03:09

Oriol