惰性 getter 在 类 中不起作用
Lazy getter doesn't work in classes
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
上面的代码应该可以正常工作,但最后一行出错了。
Uncaught TypeError: Cannot set property b of # which has only a getter(…)
显然 getter 没有在 class 中被删除,而它在对象中工作正常。我在最新的稳定 chrome.
根据设计,class 属性不可删除 -- 参考:https://github.com/jeffmo/es-class-fields-and-static-properties
实例字段初始化过程
执行字段初始值设定项的过程发生在 class 实例化时间。下面描述初始化每个 class 字段初始化器的过程(旨在 运行 每个字段按照声明的顺序进行一次):
- 让实例成为被实例化的对象。
- 设 fieldName 为当前字段的名称(存储在构造函数的槽中)。
- 设 fieldInitializerExpression 为当前字段的 thunked 初始化表达式(存储在构造函数的槽中)。
- 设 initializerResult 为 fieldInitializerExpression 的求值结果,它等于 instance。
- 设propertyDescriptor为PropertyDescriptor{[[Value]]: initializerResult, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false}.
调用实例。[[DefineOwnProperty]](fieldName, propertyDescriptor).
class 的 getter 位于 .prototype
对象上,而不是 this
,这就是为什么您尝试 delete
它失败了(并且,正如 Jeremy 指出的那样,它是不可删除的)。
但是您可以 简单地 在隐藏 getter:
的实例上创建自己的 属性
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 并抛出的继承 属性。
很明显这是关于构造函数的。当您忽略构造函数时,您使用 getter 定义的 属性 会在构造函数原型中创建,因此正确的工作方式可能应该如下所示;
class a {
get b() {
delete this.constructor.prototype.b;
return this.constructor.prototype.b = 1;
}
}
z = new a();
z.b; // 1
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
上面的代码应该可以正常工作,但最后一行出错了。
Uncaught TypeError: Cannot set property b of # which has only a getter(…)
显然 getter 没有在 class 中被删除,而它在对象中工作正常。我在最新的稳定 chrome.
根据设计,class 属性不可删除 -- 参考:https://github.com/jeffmo/es-class-fields-and-static-properties
实例字段初始化过程
执行字段初始值设定项的过程发生在 class 实例化时间。下面描述初始化每个 class 字段初始化器的过程(旨在 运行 每个字段按照声明的顺序进行一次):
- 让实例成为被实例化的对象。
- 设 fieldName 为当前字段的名称(存储在构造函数的槽中)。
- 设 fieldInitializerExpression 为当前字段的 thunked 初始化表达式(存储在构造函数的槽中)。
- 设 initializerResult 为 fieldInitializerExpression 的求值结果,它等于 instance。
- 设propertyDescriptor为PropertyDescriptor{[[Value]]: initializerResult, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false}. 调用实例。[[DefineOwnProperty]](fieldName, propertyDescriptor).
class 的 getter 位于 .prototype
对象上,而不是 this
,这就是为什么您尝试 delete
它失败了(并且,正如 Jeremy 指出的那样,它是不可删除的)。
但是您可以 简单地 在隐藏 getter:
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 并抛出的继承 属性。
很明显这是关于构造函数的。当您忽略构造函数时,您使用 getter 定义的 属性 会在构造函数原型中创建,因此正确的工作方式可能应该如下所示;
class a {
get b() {
delete this.constructor.prototype.b;
return this.constructor.prototype.b = 1;
}
}
z = new a();
z.b; // 1