0%

图解JS原型继承

话不多说,直接上图。

class Parent

1
2
3
class Parent extends Object {}
class Child extend Parent {}
const child = new Child();

对应的原型链如下:
原型链

class Parent extends Object

1
2
3
class Parent {}
class Child extend Parent {}
const child = new Child();

对应的原型链如下:
原型链

区别

以上两种写法的主要区别是 Parent 类的定义。

1
2
3
class Parent extends Object {}
// vs
class Parent {}
  • 使用 extends 关键字时,Parent__proto__ 属性指向 Object
  • 不使用 extends 关键字时,Parent__proto__ 属性指向 Functionprototype

因为 类的 __proto__ 属性始终指向父类,表示构造函数的继承。因此有 extends Object 时,Parent 的父类为 Object;没有 extends Object 时,Parent 没有显式指定父类,而类的 __proto__ 属性表示构造函数的继承,因此其 __proto__ 直接指向 Functionprototype ,这样才能形成构造函数继承链的闭环。

解析

类(构造函数)、类实例及类原型形成了三角关系,三者通过以下三个属性实现了互相连接。

  • prototype
  • __proto__
  • constructor

prototype

  • 每个函数都有的属性。(类其实就是构造函数。)
  • 用于实现基于原型链的继承。

__proto__

  • 每个对象都有的属性。(JS中函数也是对象,所以函数也有该属性。)
  • 子类的 __proto__ 属性指向父类(如 Child__proto__ 指向 Parent,表示构造函数的继承)。
  • 子类 prototype__proto__ 属性指向父类的 prototype*。(如 Child 的 *prototype__proto__ 属性指向 Parentprototype,表示方法的继承)。
  • 类对象的 __proto__ 属性指向类的 prototype 。(如 child__proto__ 指向 Childprototype )。
  • Function__proto__prototype 均指向 Functionprototype,形成闭环。

constructor

  • 每个对象都有的属性,指向其构造函数。
  • 类(构造函数)的 prototypeconstructor 属性指向该类(构造函数)自身。
  • 类(构造函数)的 constructor 属性均指向 FunctionFunctionconstructor 属性指向自身,形成闭环。

参考