JavaScript, private variables


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

Author: Юрий, 2016-04-24

3 answers

In es6, this is not possible. Many people think that the es6 classes are some new construction or implementation, no. This is the usual, new syntax for good old prototype inheritance.

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

Same as

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

Therefore, private methods are not implemented in the class, you will have to solve this problem yourself. How? For example, via 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 methods get/set are just for example, in reality, most likely they will not be, if the variable is already private. Here get/set the only ways to reach privateProp, no more, remove it get/set privateProp it will become a real private way.

UPD
I made a little mistake, the variable would be created one for all instances, as they wrote in the comments, I corrected the answer. Now it will always create its own instance of the private variable

 4
Author: ThisMan, 2016-04-24 07:57:25

For private properties, 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 - so without the privatePropSymbol variable, external code will not be able to access it.

 6
Author: Pavel Mayorov, 2017-02-02 13:13:25

And HERE IT IS (at what it is possible to do so already 200 years from birth):

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') }

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 no longer necessary to learn the names of properties from the class implementation, such as the internal handlers property, for fear of accidentally overlapping them in the inheriting classes. I have been using private ones for 6 years. And no problems with leaks. I don't understand people who say that there are no private ones in Javascript.

Enjoy, and listen less all sorts of incompetents ;)

 0
Author: Maxmaxmaximus, 2016-07-18 06:32:49