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

How do I use a static variable in ES6 class?

我正在尝试在 es6 中使用静态变量。我想在 Animal class 中声明一个静态变量 count 并增加它。但是,我无法通过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

我预计 console.log(Animal.getCount());1,但它不起作用。 如何声明静态变量并通过调用方法修改它?

您的 class 没有静态变量(如果静态变量是指静态 属性)。 getCount returns NaN (在你调用 increaseCount 之后)因为 Animal 最初没有 count 属性。然后 increaseCount 执行 undefined + 1NaN。由 new Animal 创建的 实例 最初有一个 count 属性,但 Animal 本身没有,直到您调用 increaseCountstatic 方法中的 this 指的是 Animal class(构造函数)本身(如果您通过 Animal.methodName(...) 调用它)。

你可以给 Animal 一个 count 属性:

Animal.count = 0;

实例:

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

对于 static class fields proposal(目前处于第 3 阶段),您可以在 Animal 中使用 static count = 0; 以声明方式执行此操作。 Live Example (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());

根据 private static 提案(处于第 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 配置不支持,但你可以 运行 它存在于 their REPL.


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

class Mammal extends Animal {}

然后

Mammal.increaseCount();
increaseCount 中的

this(继承自 Animal)指的是 Mammal,而不是 Animal

如果您想要该行为,请使用this。如果不这样做,请在那些 static 方法中使用 Animal

要设置静态变量,请将其设置在对象 Animal 本身上。截至目前,在 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()); 

静态 class 端属性和原型数据属性必须在 ClassBody 声明之外定义。

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

其他回答中提到,this.count指的是constructor中的实例属性。为了初始化static 属性,应该设置Animal.count

Class fields proposalAnimal.count = 0 提供语法糖,可用于转译器(Babel 等):

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

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

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

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

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

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

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

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

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

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

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

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

你可以使用闭包来模拟静态变量

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

如果你想要增量 ID:

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

可以用static getter和setter

模拟静态变量
 export class MyClass {
  static get variable() {
    return this.foo;
  }

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

然后像这样使用它

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