https://github.com/tc39/proposal-class-fields
http://2ality.com/2017/07/class-fields.html
https://2ality.com/2020/06/private-static-methods-accessors-in-classes.html
https://developers.google.com/web/updates/2018/12/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
https://2ality.com/2019/07/public-class-fields.html
Assignment("=") vs. definition("Object.defineProperty()"), 字段通过定义,而不是赋值
私有字段:
class P {
#a = 1;
// 不能被删除,只能在 class 代码块中以任何方式使用
// 由于是唯一符号,所以只能有一个(实例和静态)
// 可以 #effect in {} ,品牌检查
get a () {
return this.#a; // 已有私有字段的定义
}
}
cannot yet be private:
- Method definitions
- Setters and getters
不能通过 Proxy 访问含有私有字段的方法 // 父类实例化返回代理,getter 代替,代理方法
An upcoming proposal that fills this gap is currently at stage 3.
// https://github.com/tc39/proposal-static-class-features/
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