如何使用EcmaScript 6类实现对象封装?

时间:2015-02-10 02:17:31

标签: javascript ecmascript-6

由于Javascript中的方法很容易被反弹,一些(很多?)开发人员使用JS的词法范围来实现对象封装(即,独立于该方法当前绑定的对象的私有对象状态)。我在使用这样的承诺时发现这个特别方便:

function Something() {
    const that = this; // optional
    that.state = 0;
    this.doSomething = function() {
        console.log(that.state++);
    };
    return this;
}

const instance = new Something;
new Promise(resolve => resolve(instance)).then(instance.doSomething);
//output: 0

不幸的是,这似乎与目前的Ecmascript 6类草案不兼容。这段代码:

class SomethingES6 {
    constructor(){
        this.state = 0;
    }
    doSomething(){
        console.log(this.state++);
    }
}

const instanceES6 = new SomethingES6;
new Promise(resolve => resolve(instanceES6)).then(instanceES6.doSomething);

抛出因为doSomething方法在执行时没有绑定到instanceES6。有没有办法实现像利用"""在前面的代码片段中?

我想要一个在定义类时强制执行此行为的解决方案 - 蓝鸟&(其他人)Promise.bind不是解决方案!就个人而言,我喜欢在节点中工作的解决方案,当然,最好使用通用解决方案。

1 个答案:

答案 0 :(得分:0)

替换

new Promise(resolve => resolve(instanceES6)).then(instanceES6.doSomething);

new Promise(resolve => resolve(instanceES6)).then(_ => _.doSomething());

它更短,并通过可用的工具实现您想要的效果。

如果是这样,正如您在评论中提到的那样,对于您的首选项来说太脆弱了,您可以使用自定义函数替换.then并从原型中获取函数,检查实例是否具有它(通过使用{{1反向查找的属性+引用标识检查)然后在实例上调用它。基本上将运行时类型检查添加到promise链中。

由于javascript没有像java8这样的方法引用function.name运算符,我们必须为其原型别名:

::

class SomethingES6 { ... } const SomethingClass = SomethingES6.prototype ... new Promise(...).checkedThen(SomethingClass.doSomething); 是带有类型检查的自定义函数。由于扩展内置函数是不好的做法,因此可以先将Promise子类化,或者通过将自定义导入当前作用域来在功能上进行组合:

.checkedThen