JS两种继承写法被称等价,为何存在Object.getPrototypeOf结果差异?
为什么两种JavaScript继承实现方式在
Object.getPrototypeOf(Rabbit)判断上存在差异? 以下两种JavaScript继承实现方式常被认为等价:
构造函数原型链继承写法
function Animal() {} function Rabbit() {} Rabbit.prototype = Object.create(Animal.prototype); Rabbit.prototype.constructor = Rabbit;
ES6 Class继承写法
class Rabbit extends Animal {}
但执行console.log(Object.getPrototypeOf(Rabbit) === Animal);时却存在差异,原因如下:
构造函数写法中,
Rabbit作为普通函数,自身原型指向Function.prototype
普通函数默认的原型是Function.prototype,上述代码仅修改了Rabbit.prototype(即Rabbit实例的原型),并没有改动Rabbit这个函数自身的原型指向。因此Object.getPrototypeOf(Rabbit)返回的是Function.prototype,和Animal不相等。Class继承写法中,
extends同时修改了实例和类自身的原型链
ES6的extends语法做了两层处理:一是将Rabbit.prototype的原型指向Animal.prototype(和构造函数写法的实例原型链一致);二是直接把Rabbit这个类本身的原型设置为Animal。所以Object.getPrototypeOf(Rabbit)返回的是Animal,和Animal相等。
简单来说,构造函数写法只处理了实例的原型链,而Class的extends同时处理了实例的原型链和类(构造函数)自身的原型链。
如果要让构造函数写法和Class写法在这一点上完全等价,需要额外添加一行代码:
Object.setPrototypeOf(Rabbit, Animal);
内容的提问来源于stack exchange,提问作者刘jankin
相关产品推荐
相关产品推荐

