跳到主要内容

静态成员

static 成员与直接挂在类上有何区别?​

  • 等价: static m(){} 与 User.m = function(){} 完全同义, 前者只是写在类体里;
  • this: User.m() 中 this === User, 遵循「点号前的对象」规则;
  • 归属: 静态成员挂在类本身, 实例上访问不到;
class User {
static staticMethod() {
return this === User;
}
static planet = "Earth";
}
User.staticMethod(); // true
User.planet; // "Earth"
  • 报错示例: article.createTodays() → article.createTodays is not a function;
  • 静态属性语法与普通字段一样, 只是前置 static, 新式浏览器均支持;

静态成员适合什么场景?​

  • 整类操作: 与具体实例无关的比较、查找、保存、删除, 如 Article.compare(a, b)、Article.remove({id});
  • 工厂方法: 用 new this(...) 让子类也能复用, 返回按另一种方式构造的实例;
class Article {
constructor(title, date) {
this.title = title;
this.date = date;
}
static compare(a, b) {
return a.date - b.date;
}
static createTodays() {
return new this("Today's digest", new Date());
}
}
articles.sort(Article.compare);
Article.createTodays().title; // "Today's digest"
  • 语义: Article.compare 站在「文章之上」, 是整个类的工具, 不属于任何一篇文章;

静态成员如何被子类继承?​

  • 机制: class Rabbit extends Animal 建立两条 [[Prototype]] 链, 静态与普通成员因而都被继承;
    • Rabbit.__proto__ === Animal: 静态成员的查找路径;
    • Rabbit.prototype.__proto__ === Animal.prototype: 实例方法的查找路径;
  • 表现: Rabbit.compare 实际调用 Animal.compare, Rabbit.planet 读到 "Earth", 因为在 Rabbit 上找不到就继续查 Animal;
class Animal {
static planet = "Earth";
}
class Rabbit extends Animal {}
Rabbit.planet; // "Earth"
Rabbit.__proto__ === Animal; // true