在 ES6 中引入的 JavaScript
class
语法中(static 属性可以从类访问,instance 属性可以从实例访问):
this
属性属于实例。所以我希望实例字段属于实例的原型,就像实例方法一样。但事实并非如此,他们得到了特殊的待遇,而是属于实例,就像
this
属性一样。
例如班级
class A {
static x; // static field
static f() {} // static method
y; // instance field (special treatment)
g() {} // instance method
constructor() {this.z = 0} // this property
}
给出结果
> Object.getOwnPropertyNames(A)
[ 'length', 'name', 'prototype', 'f', 'x' ]
> Object.getOwnPropertyNames(A.prototype)
[ 'constructor', 'g' ]
> Object.getOwnPropertyNames(new A)
[ 'y', 'z' ]
以不同于实例方法的方式处理实例字段的基本原理是什么?
我看到这种特殊处理的一个缺点是它阻止了在实例的原型中简单地声明非函数属性,迫使人们在类声明之后这样做(或求助于静态初始化块):
> A.prototype.y2 = 0;
0
> Object.getOwnPropertyNames(A.prototype)
[ 'constructor', 'g', 'y2' ]
另一个缺点是,如果要在实例上声明属性,已经有
this
,所以它复制了现有的语言功能。
class
语法只是现有事物的语法糖:
prototype
- 一个在实例之间共享事物的对象,主要是方法和 get-set 描述符constructor
- 一个使用预定义原型制作对象的函数constructor
作为命名空间来保存相关的东西class
语法包括所有这些......除了原型上的常量 - 它们具有非常奇怪的行为(实际上是属性初始化器)并且没有人真正使用过它们