2016-01-19 3 views
12

Я просто пытаюсь использовать ES6 и хочу переписать часть кода, написанную на обычном javascript, на ES6. И теперь я застреваю при попытке переписать частные свойства и методы в классах ES6. Кажется, что классы в ES6 явно не предоставляют никаких личных данных или методов.Есть частные свойства и методы в классах ES6

Кроме того, я проверил эту тему: Private properties in JavaScript ES6 classes и узнал, что мы можем использовать WeakMap для хранения личных данных. Что-то вроде странно, но все же это может быть работа. И мне удалось использовать его для частных данных.

Но как насчет частных методов? Каким образом рекомендуется использовать частные методы (или даже защищенные методы) в классах ES6?

Я был бы признателен, если бы кто-нибудь мог показать мне clean способ переписать эту часть кода, используя класс ES6, а также частные методы.

Спасибо.

Вот обычный старый 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

В статье [* MDN: Classes *] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) должно быть достаточно информации. – RobG

ответ

12

Похоже, что классы в ES6 явно не обеспечивают ничего, чтобы иметь личные данные или методы.

Исправить. Синтаксис class предназначен для обычных классов с прототипными методами. Если вы хотите приватные переменные, вы поместите их в конструкторе, как всегда:

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

Кажется, все в порядке. Но, если это единственный способ, я думаю, что было бы более «чище» оставаться со старым javascript 'function()' style. Поскольку в этом случае с ES6-классами мало что можно сделать. – kabirbaidhya

+0

Ну, я бы ожидал, что у вас есть хотя бы несколько прототипов, не так ли? – Bergi

+4

«Частный» материал доступен только в конструкторе. Вы должны отказаться от использования класса getter и seters и методов класса, чтобы это работало (или, по крайней мере, те, которые включали бы якобы «частные» участники). В этом случае вы сводились к одной функции генерации объекта, которая на самом деле не отличается от «традиционных» функций класса. –

3

Вы можете использовать символы, чтобы дать своего рода-частного члена.

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

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

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

    [ ANOTHER ] = 'transpilation required' 
} 

2-й символ добавляется к классу с помощью class field, это только в предложении и потребует transpilation работать в любом месте, но все остальное работает в узле и новых браузеров.

+0

это странный синтаксис, и он слегка похож на хак, но он определенно работает и в основном эквивалентен реальным частным членам. –

+1

Я, хотя это была хорошая идея, но свойство не очень личное. Вы не можете получить доступ к значению с помощью 'instance.key', но вы все равно можете использовать' instance [Object.getOwnPropertySymbols (instance) .filter (s => s.toString(). Replace (/^Symbol \ (([^)] +) \) $ /, '$ 1') === 'key') [0]] ' – Neovov

+0

ну, вы могли бы это сделать ... – artparks

Смежные вопросы