静态成员
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