2016-01-19 11 views
12

Po prostu próbuję ES6 i chcę przepisać część kodu napisanego w zwykłym javascript na ES6. A teraz utknąłem podczas próby ponownego napisania prywatnych właściwości i metod w klasach ES6. Wygląda na to, że klasy w ES6 nie udostępniają niczego, aby mieć prywatne dane lub metody.Mieć prywatne właściwości i metody w klasach ES6

Sprawdziłem również ten wątek: Private properties in JavaScript ES6 classes i okazało się, że możemy użyć WeakMap do przechowywania prywatnych danych. Co jest dziwne, ale nadal może być pracą. I udało mi się go użyć do prywatnych danych.

Ale co z prywatnymi metodami? Jaki jest zalecany sposób posiadania prywatnych metod (lub nawet metod chronionych) w klasach ES6?

Byłbym wdzięczny, gdyby ktoś mógł mi pokazać czysty sposób przepisywania tej części kodu przy użyciu klasy ES6 wraz z prywatnymi metodami.

Dzięki.

Oto zwykły stary kod javascript:

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

Powinny być dostępne wystarczające informacje w artykule [* MDN: Classes *] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes). – RobG

Odpowiedz

12

Wydaje się zajęcia w ES6 nie przewidują wprost nic do posiadania prywatnych danych lub metod.

Prawidłowo. Składnia class dotyczy normalnych klas z prototypowymi metodami. Jeśli chcesz zmiennych prywatnych, można umieścić je w konstruktorze jak zawsze:

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

Wydaje się być w porządku. Ale jeśli jest to jedyny sposób, myślę, że byłoby bardziej "czystsze" zachowanie starego stylu 'function()' javascript. Ponieważ niewiele możemy zrobić w tym scenariuszu z klasami ES6. – kabirbaidhya

+0

Cóż, spodziewałbym się, że masz przynajmniej kilka prototypowych metod, prawda? – Bergi

+4

"Prywatne" rzeczy tutaj są dostępne tylko w konstruktorze. Musisz zrezygnować z używania klas pobierających i ustawiających oraz metod klasy, aby działały (lub przynajmniej te, które obejmowałyby rzekomo "prywatnych" członków). W takim przypadku zostaje się zredukowana do funkcji generowania pojedynczego obiektu, która tak naprawdę nie różni się od "tradycyjnych" funkcji klasowych. –

3

Można używać symboli dać sort-prywatnego członka.

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

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

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

    [ ANOTHER ] = 'transpilation required' 
} 

The 2nd symbol zostanie dodany do klasy przy użyciu class field, to tylko we wniosku i będzie wymagać transpilation pracować w dowolnym miejscu, ale reszta działa w węźle i nowych przeglądarek.

+0

to jest dziwna składnia i wydaje się nieco jak hack, ale na pewno działa i jest w zasadzie równoznaczna z prawdziwymi członkami prywatnymi. –

+1

Ja też to był dobry pomysł, ale nieruchomość nie jest tak naprawdę prywatna. Nie można uzyskać dostępu do wartości za pomocą 'instance.key', ale nadal można używać' instancji [Object.getOwnPropertySymbols (instance) .filter (s => s.toString(). Replace (/^Symbol \ (([^)] +) \) $ /, '$ 1') === 'klucz') [0]] ' – Neovov

+0

cóż, możesz to zrobić ... – artparks

Powiązane problemy