Access Modifiers (Private, Protected) in ES6

Note. I already went through the following SO and 7 answers (at the moment) about “Symbols” , “Maps of the week” and “Maps”, please read the full question before you vote: Private Property in ES6 JavaScript Classes
Article: https://esdiscuss.org/topic/es7-property-initializers

Below is my Simple Class , which contains private, public, and protected properties and methods.

  'use strict'; class MyClass { constructor () { this.publicVar = 'This is Public Variable'; this.privateVar = 'This is Private Variable'; this.protectedVar = 'This is Protected Variable'; } // Public Constructor Method. publicMethod () { console.log(' Accessing this.publicVar: ', this.publicVar); console.log(' Accessing this.privateVar: ', this.privateVar); console.log(' Accessing this.protectedVar: ', this.protectedVar); return 'Its Public Method' } // Public Method. privateMethod () {return 'Its Private Method'} // Private Method. protectedMethod () {return 'Its Protected Method'} // Protected Method. foo () { this.publicMethod(); this.privateMethod(); this.protectedMethod(); } // Public Method } // end class 

I instantiate an object and call a public method that works as expected.

 let MyObject = new MyClass; MyObject.foo(); // Works fine. console.log( MyObject.publicVar ); // Works console.log( MyObject.publicMethod() ); // Works 

Works as expected.

Now my question. I know that in the ES6 specification there are several things like Symbol, what is the current workaround for protection, and private variables / methods that work on ES6 classes.

 console.log( MyObject.privateVar ); // Works console.log( MyObject.privateMethod() ); // Works 

I want this property and method to display only in its class.

 console.log( MyObject.protectedVar ); // Works console.log( MyObject.protectedMethod() ); // Works 

I want this property and method to be visible in my class and inside classes that extend it.

Workaround / Best solution to achieve this behavior rated

+6
source share
2 answers

Private properties

In ES6 (and before), all private property implementations rely on closure .

People did this even before JavaScript had versions. WeakMap is simply a variation that eliminates the need for a new area and new functions for each new object due to access speed.

A symbol is an ES6 variant that hides an attribute from general operations, such as simple access to properties or for in .

 var MyClass; ( () => { // Define a scoped symbol for private property A. const PropA = Symbol( 'A' ); // Define the class once we have all symbols MyClass = class { someFunction () { return "I can read " + this[ PropA ]; // Access private property } } MyClass.prototype[ PropA ] = 'Private property or method'; })(); // function in the closure can access the private property. var myObject = new MyClass(); alert( myObject.someFunction() ); // But we cannot "recreate" the Symbol externally. alert( myObject[ Symbol( 'A' ) ] ); // undefined // However if someone *really* must access it... var symbols = Object.getOwnPropertySymbols( myObject.__proto__ ); alert( myObject[ symbols[ 0 ] ] ); 

As you can see above, it can be bypassed by Object.getOwnPropertySymbols () . Despite its existence, I always select a symbol over WeakMap. The code is cleaner, simpler, gc works less, and (I think) is more efficient.

I personally avoid the class . Object.create much simpler. But that goes beyond that.


Protected Properties

Protected properties, by their nature, require the executing function to know the object of the calling code in order to determine if it should be provided.

This is not possible in JS, and not because ES6 does not have a real class , but because the context of the caller is simply inaccessible .

Due to various special JavaScript natures , it remains impossible for foreseeable future protected properties.

On the other hand...


Package Properties

Some languages ​​have semi-secure properties, sometimes called "private private", where the method / property is available to members in the same module / package.

ES6 can implement it with closure. This is exactly the same as the private property code above - just share the area and its symbols with several prototypes.

But this is impractical, since this requires that the entire module be defined in the same closed area, that is, in one file. But this is an option nonetheless.

+8
source

I'm late to answer this, but in javascript you can emulate private and protected methods.

Private Methods / Properties

Uses Famous Symbol Approach

 const someMethod = Symbol() const someProperty = Symbol() export default class Parent { constructor () { this[someProperty] = 'and a private property' } [someMethod] () { console.log('this is a private method') console.log(this[someProperty]) } callPrivateMethod () { this[someMethod]() } } 

Protected Methods / Properties

By nature, protected members are visible to derived classes. They should also mimic the super.method pattern.

symbols.js

 export default { protectedMethod: Symbol() } 

parent.js

 import symbols from './symbols' const someMethod = Symbol() const someProperty = Symbol() export default class Parent { constructor () { this[someProperty] = 'and a private property' } [someMethod] () { console.log('this is a private method') console.log(this[someProperty]) } [symbols.protectedMethod] () { console.log('I am the parent') } callPrivateMethod () { this[someMethod]() } } 

child.js

 import Parent from './parent' import symbols from './symbols' export default class Child { [symbols.protectedMethod] () { console.log('I am the child') super[symbols.protectedMethod]() } callProtectedMethod () { this[symbols.protectedMethod]() } } 
0
source

All Articles