2015-12-29 7 views
6

Hinweis: Ich ging bereits durch die unter SO Frage und 7 Antworten (ab sofort) über Symbols, WeekMaps und Karten, lesen Sie bitte die volle Frage bevor Sie wählen: Private properties in JavaScript ES6 classes
Artikel: https://esdiscuss.org/topic/es7-property-initializersZugriffsmodifizierer (Private, Protected) in ES6

Unten ist mein Simple Class die privaten, öffentlichen und geschützten Eigenschaften und Methoden enthält.

'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

ich das Objekt zu erhalten und die öffentliche Methode aufrufen, die wie erwartet funktioniert.

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

wie erwartet.

Jetzt meine Frage. Ich bin mir bewusst, dass einige Dinge wie Symbol in der ES6-Spezifikation sind, was ist die aktuelle Problemumgehung, um geschützt zu werden und private Variablen/Methoden, die an ES6-Klassen arbeiten.

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

Ich möchte diese Eigenschaft und Methode sichtbar ist nur in seiner eigenen Klasse.

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

Ich mag diese Eigenschaft und Methode in seiner eigenen Klasse und innerhalb von Klassen sichtbar sein, es erstreckt.

Problemumgehung/bessere Lösung dieses Verhalten zu erreichen, sehr geschätzt wird

+4

Wenn Sie bereits über Symbole und WeakMap gelesen haben, was müssen Sie sonst noch wissen? –

+0

Ich bin durch diese gegangen, aber erwarte das Beispiel als eine Antwort zu beschränken und erweiterten Klassenbereich sowie –

+2

ES6 Klassen haben nicht privat/geschützt absichtlich: [siehe hier] (http://stackoverflow.com/a/22158732/ 2509123) WeakMap/Symbols ist eher eine Problemumgehung, um sie zu ES6-Klassen hinzuzufügen, aber ES6-Klassen sind eher eine Methode zum Definieren von Methoden, als "klassische" OO-Klassen in Sprachen wie Java und C# zu replizieren. –

Antwort

8

Privat Eigenschaften

In ES6 (und vor), alles Privateigentum Implementierungen beruht auf closure.

Menschen have been doing it noch vor JavaScript hat Versionen. WeakMap ist nur eine Variante, die den neuen Bereich und die neuen Funktionen für jedes neue Objekt auf Kosten der Zugriffsgeschwindigkeit überflüssig macht.

Symbol ist eine ES6-Variante, die das Attribut vor allgemeinen Operationen wie einfachen Eigenschaftenzugriff oder for in versteckt.

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 ] ]);

Wie oben zu sehen ist, kann es durch Object.getOwnPropertySymbols() um gearbeitet werden. Trotz seiner Existenz habe ich immer ein Wahlsymbol über WeakMap. Der Code ist sauberer, einfacher, weniger GC-Arbeit und (ich denke) effizienter.

Ich persönlich vermeide auch class. Object.create ist viel einfacher. Aber das ist nicht möglich.


Geschützte Eigenschaften

Geschützte Eigenschaften, die ihrer Natur, erfordert Funktion Ausführen der Aufgabe des anrufenden Code zu kennen, um zu beurteilen, ob es Zugriff gewährt werden soll.

Das ist unmöglich in JS, nicht weil ES6 hat no real class, sondern weil Anrufer Kontext ist simply unavailable.

Aufgrund von JavaScript sind auf absehbare Zeit geschützte Eigenschaften nicht möglich, da variousspecialnatures.

Alternativ ...


Paketeigenschaften

Einige Sprachen haben halbgeschützten Eigenschaften, manchmal auch als „Paket privat“, in dem die Methode/Eigenschaft an die Mitglieder in der gleichen zugänglich ist Modul/Paket.

ES6 kann es mit Schließung implementieren. Es ist genau das gleiche wie der oben genannte private Eigentumscode - teilen Sie den Bereich und seine Symbole nur mit mehreren Prototypen.

Dies ist jedoch unpraktisch, da dies erfordert, dass das gesamte Modul unter demselben geschlossenen Umfang definiert wird, d. H. In einer einzigen Datei. Aber es ist trotzdem eine Option.