Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Have private properties & methods in ES6 classes [duplicate]

I'm just trying out ES6 and want to rewrite a part of code written in regular javascript to ES6. And now, I'm stuck while trying to re-write the private properties and methods in ES6 classes. It seems like classes in ES6 doesn't explicitly provide anything to have private data or methods.

Also, I checked this thread: Private properties in JavaScript ES6 classes and found out that we could use WeakMap to store private data. Which is sort of weird but still it can be a work around. And I did manage to use it for private data.

But what about private methods? What is the recommended way to have private methods (or even protected methods) in ES6 classes?

I would appreciate if anyone can show me a clean way to rewrite this part of code using ES6 class along with the private methods.

Thanks.

Here's the plain old 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) {
        ...
    }
}
like image 393
kabirbaidhya Avatar asked Jan 19 '16 08:01

kabirbaidhya


2 Answers

You can use symbols to give a sort-of private member.

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 is added to the class using a class field, this is only in proposal and will require transpilation to work anywhere, but the rest works in node and new browsers.

like image 128
Matt Styles Avatar answered Nov 04 '22 20:11

Matt Styles


It seems like classes in ES6 doesn't explicitly provide anything to have private data or methods.

Correct. The class syntax is for normal classes with prototype methods. If you want private variables, you put them in the constructor as always:

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) {
            …
        };
    }
}
like image 39
Bergi Avatar answered Nov 04 '22 20:11

Bergi