Object.create、寄生组合继承和 class extends 分别做了什么?
先理解原理和示例,再练习完整口述与追问。
回答要点
实例自有字段与原型方法分开;子原型用 Object.create;父构造函数只初始化一次;class 是原型机制上的语法且有额外语义。
原理拆解
Object.create(proto) 创建新对象,并将其原型直接设为 proto,不会调用 proto 对应的构造函数。Object.create(null) 创建没有 Object.prototype 的对象,适合作为受控字典,但没有默认 toString、hasOwnProperty 等方法。
传统寄生组合继承分两步:子构造函数中调用 Parent.call(this, ...) 初始化实例字段;再让 Child.prototype = Object.create(Parent.prototype),并用属性描述符恢复 constructor 为 Child,通常设为不可枚举。这样原型建立时不需要 new Parent,避免为了连原型链又执行一次父构造函数,也避免把父类引用类型字段共享到子类原型。若还需要继承静态方法,要另外连接构造函数对象的原型链。
class Child extends Parent 会建立实例方法链与静态方法链;派生构造函数中使用 this 前必须先 super(),由父构造过程初始化实例。类方法定义在原型上且默认不可枚举,类体自动严格模式,类不能不带 new 直接调用,并且类声明有暂时性死区,所以不能说 class 与手写构造函数“完全一样”。箭头函数字段通常是每个实例自己的函数,也和原型方法不同。
示例与推演
先 Parent.call(this,name) 创建实例自有字段,再 Child.prototype=Object.create(Parent.prototype) 连接实例方法链。new Child 创建对象后,读取子方法在子原型命中,读取父方法继续向上;修改子实例自己的数组不会修改其他实例。Object.create 本身没有调用 Parent。
易错点
箭头函数不能充当传统构造函数。constructor 字段恢复只是元信息维护,真正的查找关系由原型链决定。
参考回答可直接练习口述
Object.create(proto) 创建新对象,并将其原型直接设为 proto,不会调用 proto 对应的构造函数。Object.create(null) 创建没有 Object.prototype 的对象,适合作为受控字典,但没有默认 toString、hasOwnProperty 等方法。