在类方法之外声明类属性

IT技术 javascript ecmascript-6 class-fields
2021-03-20 02:01:30

看看 x 和 y 是如何在构造函数中声明的:

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

有没有办法在函数之外声明属性,例如:

class Point {
  // Declare static class property here
  // a: 22
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

所以我想将 a 分配给 22 但我不确定我是否可以在构造函数之外但仍然在类内完成它。

2个回答

在 ES6 中直接在类上初始化属性是不可能的,目前只能以这种方式声明方法。同样的规则也适用于 ES7。

然而,它是一个提议的特性,可能会在 ES7 之后出现(目前处于第 3 阶段)。这是官方建议

此外,提案建议的语法略有不同=而不是:):

class Point {
  // Declare class property
  a = 22
  // Declare class static property
  static b = 33
}

如果您使用 Babel,您可以使用第 3 阶段的设置来启用此功能。

这是一个 Babel REPL 示例


除了在构造函数中,在 ES6 中执行此操作的另一种方法是在类定义之后执行此操作:

class Point {
  // ...
}

// Declare class property
Point.prototype.a = 22;

// Declare class static property
Point.b = 33;

这是一个很好的 SO Thread深入探讨这个主题


注意

正如Bergi在评论中提到的,建议的语法:

class Point {
  // Declare class property
  a = 22
}

只是为这段代码提供快捷方式的语法糖:

class Point {
  constructor() {
    this.a = 22;
  }
}

这两个语句都将属性分配给实例

但是,这与分配给原型并不完全相同:

class Point {
  constructor() {
    this.a = 22;  // this becomes a property directly on the instance
  }
}

Point.prototype.b = 33; // this becomes a property on the prototype

两者仍然可以通过实例获得:

var point = new Point();
p.a // 22
p.b // 33

但是获取b需要在原型链上向上,而a直接在对象上可用。

在此处输入图片说明

您可能想要添加a = 22与分配给原型不同的内容,相反,它是在构造函数中创建实例属性的非常令人困惑的糖。
2021-04-30 02:01:30
嗯是真的。嗯,谢天谢地,它是唯一的语法糖,我们总是可以依靠 js 的伟大对象inheritance:)
2021-05-01 02:01:30
你不能也用static get x(){}吗?就是想。实际上它是一样的,对吗?
2021-05-13 02:01:30
嗯,这并不是完全相同的效果,但可以是相似的。您可以使用get获取常量值或在构造函数中声明的另一个值,这与声明可以直接获取/设置的值不同
2021-05-14 02:01:30
一定要爱他们的原型:)
2021-05-19 02:01:30

@nem035 是正确的,它处于提案阶段。

但是,@nem035 的建议是将其作为类实例成员实现的一种方法。

// 在这里声明静态类属性

似乎您正在寻找声明一个静态成员。如果是,JavaScript 的方式是

class Point {
  // ...
}
Point.a = '22';

您实际期望的方式可以在 TypeScript 中完成

class Point {
     static a = 22;
}

编译后的输出将与上面的示例相同

Point.a = '22';