原型与原型链
一、首先我们需要理解如下几个属性
1、prototype
我们知道,在JavaScript中每个函数都有一个prototype属性,这个属性是指向函数的原型对象的。
所谓的**“原型”是指:在每一个JavaScript对象创建的时候,会与之关联另一个对象**——“原型”,每一个对象会从原型中**“继承”**属性
【构造函数与实例原型】
构造函数->prototype->实例原型
【关系图1】
2、proto
_proto_是每个对象(null除外)都有的属性,该属性指向该对象的原型。
var person = new Person();
person.proto === Person.prototype;
【个人理解】也就是构造函数的实例对象person的_proto_属性的结果,和构造函数的prototype属性的结果是一致的,都可以得到实例原型。
【关系图2】
【补充说明】
_proto_来自于Object.prototype,与其说_proto_是一个属性,不如说是一个getter/setter,当使用obj._proto_时,可以理解返回了Object.getPrototypeOf(obj)。
Object.getPrototypeOf(person) === Person.prototype;
3、constructor
对于每一个对象的原型,它都有一个constructor属性,该属性指向该原型所关联的构造函数。
Person === Person.prototype.constructor;
【关系图3】
二、实例与原型
当读取实例的属性时,若查找不到,就会查找与该对象关联的原型中的属性,如仍旧查找不到时,就会去查找原型的原型,直至找到最顶层为止。由于原型也是一个对象,所以原型也可以调用_proto_属性来指向原型的原型。(其实原型对象就是通过 Object 构造函数生成),具体关系如下图所示:
【关系图4】
三、原型链
【构造函数,原型与实例的关系】每一个构造函数都有一个原型对象(prototype),原型对象包含一个指向构造函数的指针(constructor),而实例中都包含一个指向原型对象的内部指针(proto)。
那么假如让原型对象等于另一个类型的实例,结果会怎样?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条。这就是所谓的原型链的基本概念。——摘自《javascript高级程序设计》。
【那么Object.prototype是否有原型呢?】
Object.prototype.proto ===null;
Object.prototype.proto 的值为 null 跟 Object.prototype 没有原型同义。
所以在查找属性的时候,查找到Object.prototype即可停止查找。
故关系图可以跟新为
【关系图5】
在上图中,由相互关联的原型组成的链状结构就是原型链(蓝色线)。
参考文章:javascript——原型与原型链 - 雅昕 - 博客园 www.cnblogs.com/loveyaxin/p…