Class fields
会继承
使用 [[Define]] 而不是 [[Set]],因为目的要让字段成为实例上的数据
字段运行在 constructor 之前,super 之后 // 所以就算覆盖父类字段还是会执行
Location:
- Static: prefix static // 相当于在构造函数上设定属性,会被子类继承
- Instance: no prefix // 相当于在构造函数中为实例设置属性
- 不在原型上,但也会出现在子类实例中 // 相当于 super()
Visibility and name. A field can be either:
- A public property with a fixed name
- A public property with a computed key
- A private field with a fixed name(不能使用 computed key,this.#priv !== this['#priv'])
Initializer: optional
Initializers are executed before the constructor
Assignment("=") vs. definition("Object.defineProperty()"), 字段通过定义,而不是赋值
私有字段:
class P {
#a = 1; // 不能在 static 方法中使用,不能被删除,只能在 class 中定义和使用
get a () {
return this.#a; // 已有私有字段的定义
}
}
cannot yet be private:
- Method definitions
- Setters and getters
An upcoming proposal that fills this gap is currently at stage 3.
Why the #? Why not declare private fields via private?
- the # clearly indicates that private fields are not properties. They are a completely different mechanism.
- if you declared private fields via private and if they looked like normal properties, property lookup would become more complicated:
https://v.qq.com/x/page/c0529qeku63.html 编程语言如何演化 — 以 JS 的 private 为例
以前技术实现:
- 命名约定(如下划线前缀)
- 名称变换(如python)
- 基于Symbol. // Object.getOwnPropertySymbols 可以访问到
- 基于闭包
- 基于WeakMap