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
属性