我正在学习新的类语法,它允许您将字段初始化代码直接放在类主体中。我感到困惑的文本措辞如下。它充分解释了新语法:
假设您正在编写一个像这样的类,其中的构造函数初始化三个字段:
class Buffer { constructor() { this.size = 0; this.capacity = 4096; this.buffer = new Uint8Array(this.capacity); } }
使用新的实例字段语法,您可以改为编写:
class Buffer { size = 0; capacity = 4096; buffer = new Uint8Array(this.capacity); }
字段初始化代码已移出构造函数,现在直接出现在类主体中。 (当然,该代码仍然作为构造函数的一部分运行。如果您没有定义构造函数,则这些字段将作为隐式创建的构造函数的一部分进行初始化。)出现在赋值左侧的
前缀已经消失了,但请注意,您仍然必须使用this.
来引用这些字段,即使是在初始化器分配的右侧。以这种方式初始化实例字段的优点是,此语法允许(但不要求)您将初始化器放在类定义的顶部,使读者清楚哪些字段将保存每个实例的状态。您可以声明不带初始值设定项的字段,只需编写字段名称,后跟分号即可。如果你这样做, 该字段的初始值将是未定义的。this.
我知道这本质上是在说“以这种方式初始化实例字段使代码更具可读性”,但是,我不知道如何将字段初始值设定项本身放在类定义的顶部使得更清楚哪个字段将保存每个实例。我希望将字段初始化代码(初始化分配)而不是字段初始值设定项放在类定义的顶部来执行此操作;我很困惑文本是指字段初始值设定项本身还是短语“此语法允许您将初始值设定项放在类定义的顶部”中的字段初始化代码
我搜索了许多不同的来源,包括 Chatgpt,但它不断改变它所认为的“初始化器”所指的内容:有时它说它指的是字段初始化代码,而有时它说它指的是初始化器本身。
首先,
class
只不过是构造函数周围的语法糖。
代码中显示的两种
class
形式都相当于此构造函数:
function Buffer() {
this.size = 0;
this.capacity = 4096;
this.buffer = new Uint8Array(this.capacity);
}
无论您定义的属性位于何处,它们都会被创建并分配给不作为类的隐式创建构造函数的一部分
Buffer
。请注意,您的类中没有多个构造函数,因此不能将隐式构造函数添加到现有构造函数中。相反,您的属性作为隐式创建的构造函数的一部分,如上所示。
顺便说一句,有一个常见的误解,即在类构造函数外部定义的属性必须在构造函数之前定义。这不是真的,这并不重要。
在这方面,构造函数体内的
property.this =
和property =
没有根本区别。常见的做法是在类构造函数中仅根据构造函数参数创建成员。显然,它们无法在参数未知的构造函数体之外进行初始化。但这不是规则,只是一种常见做法 - 原则上,您可以在其构造函数中创建所有类属性。
现在,简单介绍一下术语。您创建的类实体不是“字段”,而是“实例属性”。至于术语“初始化”,通常指的是已经创建的对象。从这个意义上说,当您在 Buffer
构造函数中引入属性时,您不一定要初始化这些属性,但您的构造函数会执行 Buffer
实例的初始化。事实上,属性也可以被初始化,它甚至可以有自己的属性和构造函数,并且它发生在创建它们的 class
初始化之前,但在创建
class
实例之后,当其初始化尚未完成时。