2015-12-29 15 views
6

Nota: ho già passato attraverso il sotto SO Domanda e 7 Risposte (a partire da ora) circa Symbols, WeekMaps e mappe, Si prega di leggere l'intero domanda prima di votare: Private properties in JavaScript ES6 classes
articolo: https://esdiscuss.org/topic/es7-property-initializersmodificatori di accesso (Private, Protected) in ES6

Qui di seguito è la mia Simple Class che contiene proprietà private, pubbliche e protette e metodi.

'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

che sto un'istanza dell'oggetto e chiamando il metodo pubblico che sta funzionando come previsto.

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

funziona come previsto.

Ora la mia domanda. Sono consapevole che alcune cose come Symbol sono nella specifica ES6, qual è l'attuale soluzione per ottenere variabili e metodi privati ​​protetti su classi ES6.

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

voglio questa proprietà e metodo per essere visibili solo nella propria classe.

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

voglio questa proprietà e metodo per essere visibile nella sua classe e le classi all'interno di estenderlo.

Soluzione/soluzione migliore per raggiungere questo comportamento è apprezzato

+4

Se hai già letto su Simboli e WeakMap, cos'altro hai bisogno di sapere? –

+0

Sono passati da quelli, ma mi aspettavo che l'esempio fosse una risposta per limitare ed estendere l'ambito di classe pure –

+2

Le classi ES6 non hanno intenzionalmente privato/protetto: [vedi qui] (http://stackoverflow.com/a/22158732/ 2509123) WeakMap/Symbols è più di una soluzione alternativa per aggiungerli nelle classi ES6, ma le classi ES6 sono più di un modo per definire metodi, piuttosto che replicare classi OO "classiche" in linguaggi come Java e C# –

risposta

8

proprietà private

In ES6 (e prima), tutte le implementazioni di proprietà privata si basano su closure.

Persone have been doing it anche prima che JavaScript abbia versioni. WeakMap è solo una variazione che elimina la necessità di nuovi scope e nuove funzioni per ogni nuovo oggetto, a un costo di velocità di accesso.

Simbolo è una variante ES6 che nasconde l'attributo dalle operazioni comuni, come l'accesso alle proprietà semplici o 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 ] ]);

Come visto sopra, può essere svolte intorno Object.getOwnPropertySymbols(). Nonostante la sua esistenza, ho sempre scelto il simbolo su WeakMap. Il codice è più pulito, più semplice, meno lavoro gc e (penso) più efficiente.

Personalmente evito lo class. Object.create è molto più semplice. Ma è fuori portata.


proprietà protette

proprietà protette, per sua natura, richiede la funzione di esecuzione di conoscere l'oggetto del codice chiamante, per giudicare se deve essere consentito l'accesso.

Ciò è impossibile in JS, non perché ES6 ha no real class, ma perché chiamante contesto è simply unavailable.

causa variousspecialnatures di JavaScript, per il prossimo futuro proprietà protette restano impossibili.

alternativa ...


proprietà della confezione

Alcune lingue hanno proprietà semi-protetta, a volte chiamato "pacchetto privata", in cui il metodo/proprietà è accessibile ai membri della stessa modulo/pacchetto.

ES6 può implementarlo con chiusura. È esattamente uguale al codice della proprietà privata sopra riportato - basta condividere l'ambito e i relativi simboli con più prototipi.

Ma questo non è pratico, poiché ciò richiede che l'intero modulo sia definito sotto lo stesso ambito chiuso, vale a dire in un singolo file. Tuttavia è un'opzione comunque.

Problemi correlati