Get to know MDN better
此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。
公有字段是可编辑、可枚举和可配置的属性。因此,不同于私有对应值(private counterpart)的是,它们参与原型的继承。
还有一些额外的语法限制:
本页面将详细介绍公共实例字段。
公有实例字段存在于类的每个已创建实例中。通过声明公共字段,可以确保该字段始终存在,而且类的定义也更加自文档化(self-documenting)。
公共实例字段会在基类的构造时(构造函数主体运行之前)或子类的 super() 返回后添加到实例中。没有初始化器的字段会被初始化为 undefined。与属性一样,字段名称也可以计算。
只在类定义时对计算字段名进行一次求值。这意味着每个类总是有一组固定的字段名,两个实例不能通过计算的名称拥有不同的字段名。计算表达式中的 this 指向类声明所处上下文的 this,而引用类名会导致 ReferenceError,因为类尚未初始化。在此表达式中,await 和 yield 按预期工作。
在字段初始化器中,this 指向正在构建的类实例,而 super 指向基类的 prototype 属性,它包含基类的实例方法,但不包含其实例字段。
每次创建新实例时,都会对字段初始化表达式进行求值。(因为每个实例的 this 值都不同,所以初始化表达式可以访问特定于实例的属性)。
表达式是同步求值的。不能在初始化表达式中使用 await 或 yield。(将初始化表达式视为被隐式封装在函数中。)
由于类的实例字段是在各自的构造函数运行之前添加的,因此可以在构造函数中访问字段的值。然而,由于派生类的实例字段是在 super() 返回后定义的,因此基类的构造函数无法访问派生类的字段。
字段是逐个添加的。字段初始化器可以引用它上面的字段值,但不能引用它下面的字段值。所有实例方法和静态方法都会事先添加并可以访问,但如果这些方法引用的字段低于正在初始化的字段,那么调用这些方法时可能会出现与预期不符的情况。
备注:这对私有字段更为重要,因为访问未初始化的私有字段会抛出 TypeError,即使该私有字段已在下面声明。(如果未声明私有字段,则会提前抛出 SyntaxError。)
由于类字段是使用 [[DefineOwnProperty]] 语义(本质上是 Object.defineProperty())添加的,因此派生类中的字段声明不会调用基类中的 setter。这种行为不同于在构造函数中使用 this.field = …。
备注:在类字段规范最终确定为[[DefineOwnProperty]]语义之前,包括 Babel 和 tsc在内的大多数转译器都将类字段转换为 DerivedWithConstructor 形式,这在类字段规范化之后造成了一些微妙的错误。
类字段不能依赖于构造函数的参数,因此字段初始化器通常会在每个实例中都求出相同的值(除非同一表达式每次求出的值都不同,例如 Date.now() 或对象初始化器)。
不过,即使声明一个空的类字段也是有好处的,因为这表明了字段的存在,从而允许类型检查程序和人类读者静态分析类的结构。
上面的代码看似重复,但考虑一下 this 被动态更改的情况:明确的字段声明清楚地表明了哪些字段一定会出现在实例中。
由于初始化器是在基类执行完成后求值的,因此你可以访问由基类构造函数创建的属性。
| ECMAScript® 2027 Language Specification # prod-FieldDefinition |
启用 JavaScript 以查看此浏览器兼容性表。