How can I create a private variable in a class (ecma6 class)?

    3 answers 3

    In es6, there is no such possibility. Many people think that es6 classes are some kind of new construction or implementation, no. This is a common, new syntax for good old prototype inheritance.

     class Animal { constructor() { this.name = "dog" } say() { alert("gaf") } } 

    Same thing as

      function Animal() { this.name = "dog" } Animal.prototype.say = function () { alert("gaf") } 

    Therefore, private methods in the class are not implemented, you have to solve this problem yourself. How? For example, through the closure

      const Animal = function () { let privateProp = "i am private"; class Animal { constructor() { this.name = "dog"; } // гетеры и сеттеры для свойства get PrivateProp() { return privateProp } set PrivateProp(value) { privateProp = value } } return new Animal(); }; let dog = new Animal(); dog.privateProp; // приватное свойство dog.privateProp = "new private prop"; // меняем приватное свойство 

    Here, the get/set methods are just for example, in reality, most likely they will not exist if the variable is already private. Here, get/set only ways to reach privateProp , no more, remove get/set privateProp will become a real private way.

    UPD
    Slightly mistaken, the variable would be created one for all instances, as written in the comment, corrected the answer. Now your private variable will always be created.

    • one
      Well, you can not do that! Now your privateProp not only private, but also static ... - Pavel Mayorov
    • @PavelMayorov can be more detailed, why can not this be done? - Yuri
    • @Yuri, in the first version, one variable was created for all instances. Therefore, if we changed it somewhere, it would change for all instances of the class. - ThisMan
    • one
      @Yuri, no, in the first version, Animal was itself a f-cie constructor, now this function, which calls the function constructor) Therefore, each call creates a new closure with the variable privateProp - ThisMan
    • 3
      Spread crutches for the future? Even if you score on performance, then for what some poor programmer should get a dog instanceof Animal = false? - Qwertiy

    For private properties, you must use closures and symbols.

      const Animal = (function () { const privatePropSymbol = Symbol("privateProp"); class Animal { // гетеры и сеттеры для свойства get PrivateProp() { return this[privatePropSymbol]; } set PrivateProp(value) { this[privatePropSymbol] = value } } Animal.prototype[privatePropSymbol] = "default value"; return Animal; })(); 

    The trick is that two characters with the same name remain two different characters — therefore, without the privatePropSymbol variable privatePropSymbol external code cannot access it.

    • You probably do not know that in ES6 you can write expressions in field names in square brackets? class Cat { [1+2](){ функция с именем '3' } } - Maxmaxmaximus
    • @ Maxmaxmaximus, where is it, if in this case the name is known in advance? - Grundy
    • @Grundy, what does the advance tell if we are talking about Symbol, how can it be known in advance? He first created the class, and then he expanded the prototype to him manually. - Maxmaxmaximus
    • @ Maxmaxmaximus, so where in the sample from this answer do you need to use the calculated method name? - Grundy
    • @PavelMayorov, is it possible? - Grundy

    And here it is (with what it can be done for 200 years):

    ES6:

     var say = Symbol() class Cat { constructor(){ this[say]() // call private } [say](){ alert('im private') } } 

    ES5:

     var say = Math.random() // pollyfill Symbol() function Cat(){ this[say]() // call private methods } Cat.prototype[say] = function(){ alert('im a private') } 

    An example of using ES6:

     var handlers = Symbol() class EventEmitter { constructor(){ this[handlers] = [] } on(handler){ this[handlers].push(handler) } emit(){ for(let handler of this[handlers]) handler() } } class Cat extends EventEmitter { } var q = new Cat() q.on // function q.emit // function q.handlers // undefined cuz PRIVATE ;) 

    And it is not necessary to learn the names of properties from the implementation of a class, such as the internal property of handlers, for fear of accidentally blocking them in the classes of heirs. I have been using private for 6 years now. And no problems with leaks. I do not understand people who say that there is no private javascript.

    Enjoy, and listen to any less stupid people;)

    • the example of ES5 is not an analogue of the example of Symbol - Grundy
    • And what problems with leaks were expected? - Vladimir Gamalyan
    • one
      There are no private properties in JavaScript, so the language is arranged. All that you have brought are workarounds that allow you to emulate private properties. This is not the same thing. Well, your version of ES5 will lead to unexpected effects for beginners when using for in or for of . From me a minus. - Dmitriy Simushev
    • "Not a single break." Too much bravado. What about q[handlers] ? - vp_arth
    • However, in fairness, I want to note that symbols are a good emulation of private properties. Only here it is undesirable to throw them in the global scope - vp_arth