原型和原型链
prototype
在JavaScript中,所有的函数都有一个prototype属性,该属性指向该函数的原型对象
1 | function Person(name){ |
函数的prototype指向的就是对象原型,这个对象是调用构造函数时创建实例的原型对象,就是说p1
和p2
的原型对象是同一个
_proto_
每个对象都会有一个属性,叫做_proto_
,该属性指向该对象的原型对象,也就是构造函数的原型属性指向的对象
constructor
每个原型都有一个constructor
属性,指向该对象的构造函数
1 | function Person(){ |
实例与原型
当读取实例中的属性的时候,如果不存在该属性,则会去查找该对象的原型对象中是否存在该属性,如果不存在,则一直向上查找,一直找到最顶部为止
1 | function Person(age){ |
可以看到p1的name
属性
显示输出了自身的属性值kerwin
当删除了对象中name属性之后,输出的是原型中的数据
原因是当对象内部不存在该属性的时候,会向上在原型中找属性,所以会输出kerwin
原型的原型
原型是随着使用构造函数创建对象时,生成的一个对象。
那么原型也是一个对象,既然是一个对象,那么它一定也有原型
它的原型其实是通过Object对象的构造函数创建的
原型链
简单回顾一下之前的知识点,
prototype
是每个函数的一个属性,指向原型对象
_proto_
是每一个对象的一个属性,指向原型对象
constructor
是每一个原型对象的一个属性,指向其绑定的构造函数
1 | 每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么假如我们让原型对象等于另一个类型的实例,结果会怎么样?显然,此时的原型对象将包含一个指向另一个原型的指针,相应的,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层次递进,就构成了原型和实例的链条,这就是所谓的原型链的概念 ----------《摘自JavaScript高级程序设计》 |
那Object.prototype的原型是什么呢?是null
图中蓝色的线就是原型链