懒惰的getter不在班级

时间:2016-06-22 20:45:40

标签: javascript ecmascript-6 getter

class a {
    get b() {
        delete this.b;
        return this.b = 1;
    }
}

var c = {
    get b() {
        delete this.b;
        return this.b = 1;
    }
}

console.log(c.b); // works as expected
console.log((new a()).b); // throws error

上面的代码应该可以正常工作,但最后一行会抛出。

  

未捕获的TypeError:无法设置仅具有getter(...)

的#的属性b

显然,getter在类中没有被删除,而它在对象中工作正常。我是最新稳定的铬合金。

Lazy Getter MDN Entry

3 个答案:

答案 0 :(得分:13)

该类的getter位于.prototype对象上,而不是this上,这就是为什么delete尝试失败的原因(正如Jeremy指出的那样,它不可删除) )。

然而,你可以简单地在阴影吸气剂的实例上创建一个自己的属性:

class a {
    get b() {
        Object.defineProperty(this, "b", { value: 1, writable: false, configurable: true })
        return this.b;
    }
}

var c = new a;
console.log(c.b); // 1

我们必须使用Object.defineProperty(),因为一个简单的赋值将找到没有setter和throws的继承属性。

答案 1 :(得分:0)

按照设计,类属性不可删除 - 参考:https://github.com/jeffmo/es-class-fields-and-static-properties

实例字段初始化过程

执行字段初始值设定项的过程发生在类实例化时。下面描述了初始化每个类字段初始值设定项的过程(打算按照声明的顺序对每个字段运行一次):

  • 让实例成为实例化的对象。
  • 让fieldName为当前字段的名称(存储在构造函数的插槽中)。
  • 让fieldInitializerExpression成为当前字段的thunked初始化表达式(存储在构造函数的插槽中)。
  • 让initializerResult成为使用此实例评估fieldInitializerExpression的结果。
  • 让propertyDescriptor为PropertyDescriptor {[[Value]]:initializerResult,[[Writable]]:true,[[Enumerable]]:true,[[Configurable]]:false}。 调用实例。[[DefineOwnProperty]](fieldName,propertyDescriptor)。

答案 2 :(得分:-1)

显然,这是关于构造函数的。当您忽略构造函数时,使用getter定义的属性会在构造函数原型中创建,因此执行该作业的正确方法可能如下所示;

class a {
    get b() {
        delete this.constructor.prototype.b;
        return this.constructor.prototype.b = 1;
    }
}
z = new a();
z.b; // 1