构造函数内部与外部的JavaScript类属性



我很难理解在构造函数内部和外部定义属性之间的区别。在下面的示例中,两个属性在实例上的访问方式相同,有什么区别?

class Foo {
constructor() {
this.bar = 1;
}
baz = 1;
}
const foo = new Foo();
console.log(foo.bar, foo.baz); // 1 1

他们做同样的事情。

在构造函数之外定义属性是新的类字段语法。如果您需要支持较旧的浏览器,请使用构造函数方法,或者使用Babel将代码首先转换为较旧的语法。

请注意,类字段在构造函数完成之前运行,或者在super调用之后运行(如果有(,或者在构造函数的最开始运行。

class Foo {
prop = console.log('Class field running');
constructor() {
this.prop2 = console.log('Constructor running');
}
}
const foo = new Foo();

相关:私有字段(也是非常新的语法(必须在构造函数之外初始化,这样类才能在编译时了解哪些字段是私有的:

class Foo {
constructor() {
this.bar = 1;
// Not OK:
// this.#foo = 1;
}
// OK:
#baz = 1;
}
const foo = new Foo();

构造函数初始化允许使用类实例化中的值,因此每个实例的值可能不同,而类范围中定义的属性对所有实例都是全局的。

如果你想用实例中的值初始化一个属性,你需要在构造函数中完成。通常,如果您希望一个属性对所有实例都是通用的,您可以在构造函数之外定义它,但如果需要,也可以在内部定义。

实际上,在ES6中,在构造函数中定义this.bar被认为是脏代码。您可以通过添加属性来展开任何对象。在ES5及更低版本中就是这样做的。

ES6主要只是语法糖,这意味着所有的类定义都可以归结为"语法糖";"本地";JavaScript代码。在幕后,你对baz的定义将以你定义bar的方式出现在成绩单中。然而,为了可读性,在ES6中添加了语法糖,以便以更类似类的方式定义属性。

最新更新