JavaScript 中的“类字段”是什么?

Aad*_*rma 5 javascript ecmascript-6 ecmascript-next class-fields

我正在阅读有关 JavaScript 类的内容,并遇到了“公共类字段语法”这个术语。在深入研究它时,我遇到了这个Babel 关于类属性的文档

有人可以解释一下 - 在实现方面,这种新语法的用例是什么? (它为 JavaScript 提供了哪些解决方案/好处,哪些是迄今为止缺失的?)

下面是一个例子(在谷歌浏览器中运行没有错误)

class Person {
    firstName = "Mike";
    lastName = "Patel";
    
    // this is a public class field syntax
    getName = () => {
      return this.firstName + " " + this.lastName;
    };
}

var p = new Person();

console.log(p.firstName); // Mike
console.log(p.lastName); // Patel
console.log(p.getName); // () => { return this.firstName + " " + this.lastName; }
console.log(typeof p.getName); // function
console.log(p.getName()); // Mike Patel
Run Code Online (Sandbox Code Playgroud)

VLA*_*LAZ 12

简单地说,使用它的原因是易于理解代码。没有类字段声明,你会做类似的事情

class Person {
  constructor() {
    this.firstName = "Mike";
    this.lastName = "Patel";

    this.getName = () => {
      return this.firstName + " " + this.lastName;
    };
  }
}

var p = new Person();

console.log(p.firstName); // Mike
console.log(p.lastName); // Patel
console.log(p.getName); // () => { return this.firstName + " " + this.lastName; }
console.log(typeof p.getName); // function
console.log(p.getName()); // Mike Patel
Run Code Online (Sandbox Code Playgroud)

这是有效的,但现在您已经在构造函数中收集了所有方法声明实例属性。但是,您可以拥有更多方法,这意味着您的类定义总体上看起来毫无意义:

class MyClass() {
  constructor(someArg) {
    this.prop1 = 1;
    this.prop2 = 2;
    this.prop3 = 3;
    this.prop4 = someArg;

    this.method1 = () => {}
    this.method2 = () => {}
    this.method3 = () => {}
    this.method4 = () => {}
  }
}
Run Code Online (Sandbox Code Playgroud)

等等。同样,一切都在构造函数中。如果您有很多代码,则很难阅读什么是什么。如果构造函数接受任何参数,那么您将有额外的开销来跟踪这些参数。简而言之,它很难阅读,很难维护,没有真正的好处。你把所有东西都塞在同一个地方。

使用类字段声明,你将它们分开,你会得到

class MyClass() {
  /* properties - don't depend on the constructor*/
  prop1 = 1;
  prop2 = 2;
  prop3 = 3;
  prop4; /* this is a property that this class will have - 
          I don't need to look at the constructor to know about it */

  /* easy to see what the constructor does that is only about *constructing* the object */
  constructor(someArg) {
    this.prop4 = someArg;
  }

  /* methods are separated from the rest of the properties and construction logic */
  method1 = () => {}
  method2 = () => {}
  method3 = () => {}
  method4 = () => {}
}
Run Code Online (Sandbox Code Playgroud)

所以,总而言之,它不是革命性的,但它的语法稍微好一些,可以更容易地表达一个类的内容。

  • 非常感谢@Bergi。我确实对我使用的术语很草率。我重新措辞以避免混淆。 (2认同)
  • 但是类方法不是保存在原型中的吗?在上面的第一个示例中,由于“getName”方法位于构造函数方法中,因此它将在每个对象中创建。如果它只是一个常用的类方法,那么它将是 Person.prototype 对象的一部分,因此不会在该类创建的每个对象中重现。 (2认同)

Jon*_*lms 7

引用类字段提案

通过预先声明字段,类定义变得更加自文档化;实例经历的状态转换较少,因为声明的字段始终存在。

类字段的引入还允许私有类字段,这也带来了一些好处:

通过定义类外部不可见的内容,ESnext 提供了更强大的封装,确保类的用户不会意外地因依赖内部结构而陷入困境,这可能会更改版本。