简体   繁体   English

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

[英]How do I use a static variable in ES6 class?

I'm trying to use a static variable in es6.我正在尝试在 es6 中使用静态变量。 I'd like to declare a static variable count in Animal class and increase it.我想在Animal类中声明一个静态变量count并增加它。 However, I couldn't declare a static variable through static count = 0;但是,我无法通过static count = 0;声明一个静态变量static count = 0; , so I tried another way like this: ,所以我尝试了另一种方式:

 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

I expected console.log(Animal.getCount());我期望console.log(Animal.getCount()); to be 1 , but it doesn't work.1 ,但它不起作用。 How do I declare a static variable and modify it by calling a method?如何声明静态变量并通过调用方法对其进行修改?

Your class has no static variables (if by static variable you mean static property).您的类没有静态变量(如果静态变量是指静态属性)。 getCount returns NaN (after you call increaseCount ) because Animal has no count property initially. getCount返回NaN (在您调用increaseCount ),因为Animal最初没有count属性。 Then increaseCount does undefined + 1 which is NaN .然后increaseCountundefined + 1NaN Instances created by new Animal have a count property initially, but Animal itself does not until you call increaseCount .new Animal创建的实例最初具有count属性,但Animal本身直到您调用increaseCount this within a static method refers to the Animal class (constructor function) itself (if you call it via Animal.methodName(...) ). static方法中的this指的是Animal类(构造函数)本身(如果您通过Animal.methodName(...)调用它)。

You could give Animal a count property:你可以给Animal一个count属性:

Animal.count = 0;

Live Example:现场示例:

 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());

With the static class fields proposal (currently at Stage 3), you could do that declaratively with static count = 0;使用静态类字段提案(目前处于第 3 阶段),您可以声明性地使用static count = 0; in Animal .Animal Live Example (Stack Snippets' Babel configuration seems to support it) :实时示例(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());

With the private static proposal (at Stage 3 and actively being implemented), you could even make count private:使用私有静态提案(在第 3 阶段并正在积极实施),您甚至可以将count私有:

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());

Stack Snippets' Babel config doesn't support that, but you can run it live in their REPL . Stack Snippets 的 Babel 配置不支持这一点,但您可以在他们的 REPL 中实时运行它。


Side note: Using this within a static method to refer to the class (constructor function) is a bit tricky if there are subclasses, because for instance, if you had:旁注:如果有子类,在静态方法中使用this来引用类(构造函数)有点棘手,因为例如,如果你有:

class Mammal extends Animal {}

and then进而

Mammal.increaseCount();

this within increaseCount (which it inherits from Animal ) refers to Mammal , not Animal . this increaseCount (它继承自Animal )是指Mammal ,而不是Animal

If you want that behavior, use this .如果您想要这种行为,请使用this If you don't, use Animal in those static methods.如果不这样做,请在这些static方法中使用Animal

As mentioned in other answers, this.count refers to instance property in constructor .正如其他答案中提到的, this.count指的是constructor实例属性。 In order for static property to be initialized, Animal.count should be set.为了初始化静态属性,应该设置Animal.count

Class fields proposal provides syntactic sugar for Animal.count = 0 that is available with transpilers (Babel, etc):类字段提案Animal.count = 0提供了语法糖,可用于转译器(Babel 等):

class Animal {
  static count = 0;
  ...
}

An alternative in ES6 is to use initial values, in this case Animal.count initial value doesn't need to be set explicitly, eg: ES6 中的另一种选择是使用初始值,在这种情况下, Animal.count初始值不需要显式设置,例如:

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

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

Accessor methods aren't welcome in JavaScript classes - this is what getter/setter descriptors are for: JavaScript 类中不欢迎访问器方法 - 这就是 getter/setter 描述符的用途:

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

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

  static set count(v) {
    this._count = v;
  }
}

Static-only class is considered antipattern in JavaScript because a state or other traits that are specific to classes aren't used.仅静态类在 JavaScript 中被视为反模式,因为不使用特定于类的状态或其他特征。 In case there should be only one instance, plain object should be used (unless there are other concerns that could benefit from class ):如果应该只有一个实例,应该使用普通对象(除非有其他可以从class受益的问题):

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

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

  set count(v) {
    this._count = v;
  }
};

Static class-side properties and prototype data properties must be defined outside of the ClassBody declaration.静态类端属性和原型数据属性必须在 ClassBody 声明之外定义。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

 class Animal { static increaseCount() { Animal.count += 1; } static getCount() { return Animal.count; } } Animal.count = 0; Animal.increaseCount(); console.log(Animal.getCount()); // undefined

To set a static variable, set it on the object Animal itself.要设置静态变量,请将其设置在对象 Animal 本身上。 As of now in Javascript you cannot directly declare static properties inside classes like you can declare static methods.截至目前,在 Javascript 中,您不能像声明静态方法那样直接在类中声明静态属性。

class Animal {
    constructor() {
    }

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

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

you can use closures to simulate static variables您可以使用闭包来模拟静态变量

 const Animal= (() => { let count= 0; class Animal { constructor() {} static increaseCount() { count += 1; } static getCount() { return count; } } return Animal; })(); console.log(Animal.getCount()); Animal.increaseCount(); console.log(Animal.getCount());

If you want to have incremential ids:如果您想拥有增量 ID:

 constructor() {
    super(template);
    if (typeof MyClass.nextId == 'undefined') {
    MyClass.nextId = 0;
    }
    this._id = `${MyClass.nextId++}`;
 }

You can simulate static variables with static getter and setter您可以使用静态 getter 和 setter 模拟静态变量

 export class MyClass {
  static get variable() {
    return this.foo;
  }

  static set variable(foo) {
    this.foo = foo;
  }
}

And use it like this并像这样使用它

  MyClass.variable = 'bar';
  console.log(MyClass.variable);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM