拥有ES6课程中的私有属性和方法

kab*_*hya 13 javascript class ecmascript-6

我只是尝试ES6,并希望将常规javascript中编写的代码部分重写为ES6.现在,我在尝试重写ES6类中的私有属性和方法时遇到困难.似乎ES6中的类没有明确地提供任何私有数据或方法.

此外,我检查了这个线程:JavaScript ES6类中的私有属性,发现我们可以使用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) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

Ber*_*rgi 13

似乎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) {
            …
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 似乎没问题.但是,如果这是唯一的方法,那么我认为使用旧的javascript`function()`样式会更"干净".因为在ES6课程的这种情况下我们无能为力. (4认同)
  • 这里的"私有"内容仅在构造函数中可用.你必须放弃使用类getter和setter以及类方法才能工作(或者至少要涉及所谓的"私有"成员).在这种情况下,您将简化为单个对象生成函数,这与"传统"类函数没有任何不同. (4认同)

Mat*_*les 5

您可以使用符号来提供某种私有成员。

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

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

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

  [ ANOTHER ] = 'transpilation required'
}
Run Code Online (Sandbox Code Playgroud)

第二个符号是使用类字段添加到类中的,这只是在建议中,需要转译才能在任何地方工作,但其余的在节点和新浏览器中工作。

  • 我虽然这也是一个好主意,但该财产并不是真正的私人财产。您无法使用 `instance.key` 访问该值,但您仍然可以使用 `instance[Object.getOwnPropertySymbols(instance).filter(s => s.toString().replace(/^Symbol\(([^)]]) +)\)$/, '$1') === 'key')[0]]` (2认同)