如何在ES6类中使用静态变量?

Cae*_*133 7 javascript ecmascript-6 es6-class

我正在尝试在es6中使用静态变量.我想countAnimal类中声明一个静态变量并增加它.但是,我无法通过声明静态变量static count = 0;,所以我尝试了另外一种方式:

class Animal {
  constructor() {
    this.count = 0;
  }

  static increaseCount() {
    this.count += 1;
  }

  static getCount() {
    return this.count;
  }
}

console.log(Animal.increaseCount()); // undefined
console.log(Animal.getCount()); // NaN
Run Code Online (Sandbox Code Playgroud)

我希望console.log(Animal.getCount());如此1,但它不起作用.如何通过调用方法声明静态变量并对其进行修改?

T.J*_*der 8

您的类没有静态变量(如果静态变量,则表示静态属性).getCount返回NaN(在你调用之后increaseCount)因为最初Animal没有count属性.那increaseCount是做undefined + 1什么的NaN.最初创建的实例最初new Animal具有count属性,但Animal直到您调用才会生成increaseCount.this在一个static方法中引用Animal类(构造函数)本身(如果你通过它调用它Animal.methodName(...)).

你可以给Animal一个count房产:

Animal.count = 0;
Run Code Online (Sandbox Code Playgroud)

实例:

class Animal {
  constructor() {
  }

  static increaseCount() {
    this.count += 1;
  }

  static getCount() {
    return this.count;
  }
}
Animal.count = 0;

Animal.increaseCount();
console.log(Animal.getCount());
Animal.increaseCount();
console.log(Animal.getCount());
Run Code Online (Sandbox Code Playgroud)

使用静态类字段提议(目前处于阶段3),您可以使用static count = 0;in 以声明方式执行此操作Animal.实例(Stack Snippets的Babel配置似乎支持它):

class Animal {
  constructor() {
  }

  static count = 0;
  
  static increaseCount() {
    this.count += 1;
  }

  static getCount() {
    return this.count;
  }
}

Animal.increaseCount();
console.log(Animal.getCount());
Animal.increaseCount();
console.log(Animal.getCount());
Run Code Online (Sandbox Code Playgroud)


旁注:this如果有子类,在静态方法中使用引用类(构造函数)有点棘手,因为例如,如果你有:

class Mammal extends Animal {}
Run Code Online (Sandbox Code Playgroud)

然后

Mammal.increaseCount();
Run Code Online (Sandbox Code Playgroud)

thisincreaseCount(它继承自Animal)指的是Mammal,而不是Animal.

如果您想要这种行为,请使用this.如果不这样做,请使用Animal这些static方法.

  • @OhadR - 不,你不是在做梦。:-) V8(在 Chrome、Node.js、Brave、Chromium、新 Edge 等中)和 SpiderMonkey(在 Firefox 75+ 中)都开始支持“静态”公共字段。Safari 仍在进行中。 (3认同)
  • 在`Animal`类中是否允许`static count = 0;`?它会导致 `SyntaxError: Unexpected token`。我在 Webpack 中使用 Babel。 (2认同)

Est*_*ask 5

如其他答案中所述,this.count是指中的实例属性constructor。为了初始化静态属性,Animal.count应进行设置。

类字段建议提供Animal.count = 0了编译器可以使用的语法糖(Babel等):

class Animal {
  static count = 0;
  ...
}
Run Code Online (Sandbox Code Playgroud)

ES6中的一种替代方法是使用初始值,在这种情况下,Animal.count不需要显式设置初始值,例如:

class Animal {    
  static increaseCount() {
    this.count = this.getCount() + 1;
  }

  static getCount() {
    return this.count || 0;
  }
}
Run Code Online (Sandbox Code Playgroud)

JavaScript类中不欢迎访问器方法-这是getter / setter描述符的用途:

class Animal {    
  static increaseCount() {
    this._count += 1;
  }

  static get count() {
    return this._count || 0;
  }

  static set count(v) {
    this._count = v;
  }
}
Run Code Online (Sandbox Code Playgroud)

纯静态类在JavaScript中被视为反模式,因为未使用特定于类的状态或其他特征。如果只有一个实例,则应使用普通对象(除非还有其他可从中受益的问题class):

const animal = {    
  increaseCount() {
    this._count += 1;
  },

  get count() {
    return this._count || 0;
  },

  set count(v) {
    this._count = v;
  }
};
Run Code Online (Sandbox Code Playgroud)