class
class 如何声明与实例化?
class Person {} // 声明
const Animal = class {}; // 表达式
- 实例化: 必须用
new, 否则抛错; new的步骤: 创建对象 → 把对象[[Prototype]]指向constructor.prototype→ 把this指向该对象 → 执行constructor→ 返回该对象 (除非constructor返回对象);constructor: 可选, 缺省为空函数, 用于定义实例属性与方法;
实例成员、原型方法与静态方法有什么区别?
- 实例成员: 在
constructor中用this定义, 各实例相互隔离; - 原型方法: 定义在
class.prototype上, 实例间共享; - 静态方法: 用
static定义, 挂在类本身, 无需实例即可调用;
class Person {
constructor() {
this.locate = () => console.log("instance", this);
}
locate() {
console.log("prototype", this);
}
static locate() {
console.log("class", this);
}
}
方法与访问器中的 this 如何处理?
- 普通方法: this 取决于调用点, 被借出后指向新调用者;
- 箭头函数字段: this 在创建时绑定到实例, 但每个实例各持一份函数;
bind: 在constructor中绑定可让 this 固定且方法共享;
class Test {
color = "red";
fun() {
console.log(this.color);
}
arrow = () => {
console.log(this.color);
};
}
const instance = new Test();
const a = { color: "green", fun: instance.fun, arrow: instance.arrow };
instance.fun(); // red
instance.arrow(); // red
a.fun(); // green; 重新绑定
a.arrow(); // red; 保持定义时 this
- 访问器: 用
get/set定义, 只定义get表示只读, 只定义set表示只写;
继承如何工作, super 有什么限制?
- 声明:
class Sub extends Super, 子类继承父类的属性与方法; super(): 调用父类构造函数并把结果赋给子类 this, 必须在子类constructor中this之前调用;- 缺省: 不写
constructor时自动调用super(...args); super限制: 只能出现在子类constructor与静态方法中;
class Bus extends Vehicle {
constructor() {
super();
console.log(this instanceof Vehicle); // true
}
}
如何禁止实例化并要求子类实现方法?
- 抽象基类: 在
constructor检查new.target === 基类时抛错; - 强制实现: 检查实例上是否存在约定方法;
class Vehicle {
constructor() {
if (new.target === Vehicle) throw new Error("Vehicle cannot be directly instantiated");
if (!this.foo) throw new Error("Inheriting class must define foo()");
}
}
如何模拟多类继承?
- mixin: 用接收父类并返回子类的函数叠加能力;
- 限制: 一个对象只有一个
[[Prototype]], 一个类只能extends一个父类; - 基础做法: 把方法对象合并进
prototype, 即下面的FooMixin, 或Object.assign(User.prototype, mixin);
const FooMixin = (Superclass) =>
class extends Superclass {
foo() {
console.log("foo");
}
};
class Bus extends FooMixin(Vehicle) {}
- 完整机制: mixin 内
super的[[HomeObject]]查找规则与eventMixin事件混入示例见 mixin 多重继承;
class 的本质是什么?
- 类型:
typeof Person === "function", 类是一个特殊的函数; - 原型: 具有
prototype属性, 其原型对象的constructor指回类本身; - 底层实现: 继承关系由寄生式组合继承实现, 见 继承模式;