话不多说,直接上图。
class Parent
1 | class Parent extends Object {} |
对应的原型链如下:
class Parent extends Object
1 | class Parent {} |
对应的原型链如下:
区别
以上两种写法的主要区别是 Parent
类的定义。
1 | class Parent extends Object {} |
- 使用
extends
关键字时,Parent
的 __proto__ 属性指向Object
。 - 不使用
extends
关键字时,Parent
的 __proto__ 属性指向Function
的 prototype。
因为 类的 __proto__ 属性始终指向父类,表示构造函数的继承。因此有 extends Object
时,Parent
的父类为 Object
;没有 extends Object
时,Parent
没有显式指定父类,而类的 __proto__ 属性表示构造函数的继承,因此其 __proto__ 直接指向 Function
的 prototype ,这样才能形成构造函数继承链的闭环。
解析
类(构造函数)、类实例及类原型形成了三角关系,三者通过以下三个属性实现了互相连接。
- prototype
- __proto__
- constructor
prototype
- 每个函数都有的属性。(类其实就是构造函数。)
- 用于实现基于原型链的继承。
__proto__
- 每个对象都有的属性。(JS中函数也是对象,所以函数也有该属性。)
- 子类的 __proto__ 属性指向父类(如
Child
的 __proto__ 指向Parent
,表示构造函数的继承)。 - 子类 prototype 的 __proto__ 属性指向父类的 prototype*。(如
Child
的 *prototype 的 __proto__ 属性指向Parent
的prototype
,表示方法的继承)。 - 类对象的 __proto__ 属性指向类的 prototype 。(如 child 的 __proto__ 指向
Child
的 prototype )。 Function
的 __proto__ 和 prototype 均指向Function
的 prototype,形成闭环。
constructor
- 每个对象都有的属性,指向其构造函数。
- 类(构造函数)的 prototype 的 constructor 属性指向该类(构造函数)自身。
- 类(构造函数)的 constructor 属性均指向
Function
,Function
的 constructor 属性指向自身,形成闭环。