JavaScript 原型与原型链
基本概念
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念
- 构造函数
Person - 原型对象
Person.prototype - 原型对象都包含一个指向构造函数的指针
constructor - 实例都包含一个指向原型对象的内部指针
person --- __proto__ > Person.prototype - 结果:
Person.prototype===obejct?
=> 由上推出条件一:Person.prototype.__proto__ == obejct.__proto__,条件二:object.__proto__ == Object.prototype - 从而推出
Person.prototype.__proto__ === Object.prototype
每一个对象都有 __proto__ 属性, 指向对应的构造函数的 prototype 属性.
class 为构造函数的语法糖, 数据类型是函数,类本身就指向构造函数。

图中由相互关联的原型 (__proto__) 组成的链状结构就是原型链,也就是由 __proto__ 连接的这条线.
类的实例对象
类的所有实例共享一个原型对象.
1 | class Point { |
p1 p2 都为 Point 的实例,它们的原型 (p1.__proto__, p2.__proto__) 都等于 Point.prototype.
可以通过实例的 __proto__ 给类添加方法,且所有共享.
类的继承
class 为构造函数的语法糖. 同时有 prototype 和 __proto__ 属性. 则存在两条继承链.
- 子类的
__proto__属性表示构造函数的继承,总是指向父类. - 子类
prototype属性的__proto__属性表示方法的继承,总是指向父类的prototype属性
1 | class Animal { |
- 作为对象,子类(Dog)的
__proto__属性是父类(Animal) - 作为构造函数,子类(Dog)的
prototype属性的__proto__属性是父类的prototype属性