2016-01-19 18 views
12

Ich versuche gerade ES6 und möchte einen Teil des in regulärem Javascript geschriebenen Codes in ES6 umschreiben. Und jetzt stehe ich fest, während ich versuche, die privaten Eigenschaften und Methoden in ES6-Klassen neu zu schreiben. Es sieht so aus, als ob Klassen in ES6 explizit nichts bieten, um private Daten oder Methoden zu haben.Habe private Eigenschaften und Methoden in ES6-Klassen

Außerdem habe ich diesen Thread überprüft: Private properties in JavaScript ES6 classes und festgestellt, dass wir WeakMap verwenden können, um private Daten zu speichern. Was irgendwie komisch ist, aber trotzdem kann es ein Work around sein. Und ich habe es geschafft, es für private Daten zu verwenden.

Aber was ist mit privaten Methoden? Was ist die empfohlene Methode, um private Methoden (oder sogar geschützte Methoden) in ES6-Klassen zu haben?

Ich würde mich freuen, wenn mir jemand eine saubere Möglichkeit zeigen könnte, diesen Teil des Codes mit ES6-Klasse zusammen mit den privaten Methoden neu zu schreiben.

Danke.

Hier ist der gute alte Javascript-Code:

function Deferred() { 

    // Private data 
    var isPending; 
    var handlers = { 
     resolve: [], 
     reject: [], 
     notify: [] 
    }; 

    // Initialize the instance 
    init(); 

    function init() { 
     isPending = true; 
     this.promise = new Promise(this); 
    } 

    // Public methods 
    this.resolve = function(value) { 
     trigger('resolve', value); 
    }; 

    this.reject = function(reason) { 
     trigger('reject', reason); 
    }; 

    this.notify = function(value) { 
     trigger('notify', value); 
    }; 

    this.on = function(event, handler) { 
     ... 
    }; 

    // Private method 
    function trigger (event, params) { 
     ... 
    } 
} 
+0

Es sollte ausreichende Informationen im Artikel [* MDN: Classes *] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) geben. – RobG

Antwort

12

Es scheint, wie Klassen in ES6 nicht ausdrücklich etwas bieten private Daten oder Methoden zu haben.

Korrekt. Die class Syntax ist für normale Klassen mit Prototypmethoden. Wenn Sie private Variablen wollen, setzen Sie sie in dem Konstruktor wie immer:

class Deferred { 
    constructor() { 
     // initialise private data 
     var isPending = true; 
     var handlers = { 
      resolve: [], 
      reject: [], 
      notify: [] 
     }; 

     // Private method 
     function trigger(event, params) { 
      ... 
     } 

     // initialise public properties 
     this.promise = new Promise(this); 

     // and create privileged methods 
     this.resolve = trigger.bind(null, 'resolve'); 
     this.reject = trigger.bind(null, 'reject'); 
     this.notify = trigger.bind(null, 'notify'); 

     this.on = function(event, handler) { 
      … 
     }; 
    } 
} 
+3

Scheint in Ordnung zu sein. Aber, wenn das der einzige Weg ist, dann denke ich, es wäre "sauberer", mit dem alten JavaScript 'function()' Stil zu bleiben. Da es in diesem Szenario mit ES6-Klassen nicht viel zu tun gibt. – kabirbaidhya

+0

Nun, ich würde erwarten, dass Sie zumindest einige Prototyp-Methoden haben, nicht wahr? – Bergi

+4

Die "privaten" Sachen hier sind nur im Konstruktor verfügbar. Sie müssen darauf verzichten, Klassen-Getter und Setter und Klassenmethoden zu verwenden (oder zumindest solche, die die vermeintlich "privaten" Mitglieder betreffen). In diesem Fall werden Sie auf eine einzige Objektgenerierungsfunktion reduziert, die sich nicht wirklich von "traditionellen" Klassenfunktionen unterscheidet. –

3

Sie Symbole verwenden können, eine Art-privaten Mitglied zu geben.

const KEY = Symbol('key') 
const ANOTHER = Symbol('another') 

class Foo { 
    constructor() { 
    this[ KEY ] = 'private' 
    } 

    say() { 
    console.log(this[ KEY ]) 
    } 

    [ ANOTHER ] = 'transpilation required' 
} 

Das zweite Symbol zur Klasse hinzugefügt wird, ein class field verwendet wird, ist dies in Vorschlag nur und transpilation benötigt, überall zu arbeiten, aber der Rest in Knoten und neue Browsern funktioniert.

+0

das ist komische Syntax, und fühlt sich ein wenig wie ein Hack, aber es funktioniert definitiv und ist im Grunde gleichbedeutend mit echten privaten Mitgliedern. –

+1

Ich dachte, das war eine gute Idee, aber das Hotel ist nicht wirklich privat. Sie können nicht auf den Wert mit 'instance.key' zugreifen, aber Sie können immer noch 'instance [Object.getOwnPropertySymbols (instance) .filter (s => s.toString(). Replace (/^Symbol \ (([^)] +) \) $ /, '$ 1') === 'key') [0]] ' – Neovov

+0

nun, du könntest das tun ... – artparks

Verwandte Themen