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

不能通过 Proxy 访问含有私有字段的方法 // 父类实例化返回代理getter 代替代理方法

An upcoming proposal that fills this gap is currently at stage 3.


Why the #? Why not declare private fields via private?

  1. the # clearly indicates that private fields are not properties. They are a completely different mechanism.
  2. 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