2016-01-19 27 views
12

我只是尝试了ES6,并且想要将使用常规JavaScript编写的代码的一部分改写为ES6。而现在,我在试图重新编写ES6类中的私有属性和方法时遇到困难。似乎ES6中的类没有明确提供任何具有私有数据或方法的东西。在ES6类中有私有属性和方法

此外,我检查了这个线程:Private properties in JavaScript ES6 classes,并发现我们可以使用WeakMap来存储私人数据。这有点奇怪,但仍然可以解决。我确实设法将它用于私人数据。

但私人方法呢?在ES6类中使用私有方法(甚至受保护的方法)的建议方法是什么?

如果有人能告诉我一个干净我会很感激的方式来重写这部分代码使用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()'风格会更“干净”。由于在ES6类的情况下我们可以做的不多。 – kabirbaidhya

+0

我希望你至少有一些原型方法,不是吗? – Bergi

+4

这里的“私人”东西只在构造函数中可用。你必须放弃使用类getter和setter以及类方法才能工作(或者至少会涉及所谓的“私人”成员)。在这种情况下,你被简化为单个对象生成函数,这与“传统”类函数没有任何区别。 –

3

您可以使用符号给一个排序的私有成员。

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

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

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

    [ ANOTHER ] = 'transpilation required' 
} 

第二符号添加到使用class field类,这只是建议,并要求transpilation在任何地方工作,但其余的节点和新的浏览器上运行。

+0

这是一个奇怪的语法,感觉有点像黑客,但它绝对有效,基本上等同于真正的私人成员。 –

+1

虽然这也是一个好主意,但是这个属性并不是真正的私人。你不能用'instance.key'访问这个值,但你仍然可以使用'instance [Object.getOwnPropertySymbols(instance).filter(s => s.toString()。replace(/^Symbol \(([^)] +)\)$ /,'$ 1')==='key')[0]]' – Neovov

+0

好吧,你可以这样做... – artparks