构造函数,原型对象,实例对象,原型链之间的关系

一、构造函数,原型对象,实例对象三者之间的关系

每创建一个函数,该函数都会自动带有一个prototype属性。该属性是一个指针,指向一个对象,该对象称之为原型对象(js中一切继承都是用原型对象实现的!)

原型对象上默认有一个属性constructor,该属性也是一个指针,指向其相关联的构造函数。

通过调用构造函数产生的实例对象,都拥有一个内部属性_proto_,指向了原型对象。其实例对象能够访问原型对象上的所有属性和方法

总结:三者的关系是,每个构造函数都有一个原型对象,原型对象上包含着一个指向构造函数的指针,而实例都包含着一个指向原型对象的内部指针。通俗的说,实例可以通过内部指针访问到原型对象,原型对象可以通过constructor找到构造函数。示例:


以上代码定义了一个构造函数People(),People.prototype指向原型对象,其自带属性construtor又指回了People,即People.prototype.constructor==People.实例对象person由于其内部指针指向了原型对象,所以可以访问原型对象上的showType方法。

二、原型链

在第一部分我们说到,所有的实例都有一个内部指针指向他的原型对象,并且可以访问到原型对象上的所有属性和方法。person实例对象指向了People的原型对象,可以访问People原型对象上的所有属性和方法。如果People原型对象变成了某一个类的实例dog,这个实例又会指向一个新的原型对象DOG,那么person此时能访问dog的实例属性和DOG原型对象上的所有属性和方法了。同理新的原型对象DOG碰巧有事另外一个对象的实例cat,这个对象实例指向原型对象CAT,那么person就能访问cat的实例属性和CAT原型上的属性和方法了。


以上代码,首先先定义了People构造函数,通过new People()得到实例,会包含一个实例对象type和一个原型属性showType。另外定义一个Cat构造函数,然后情况发生变化,本来构造函数Cat的prototype会执行cat的原型对象,但是我们这里稍有改变,将Cat构造函数的prototype指向了People实例对象覆盖了Cat的原型对象。当Cat的实例对象cat去访问type属性时,js首先在cat实例属性中查找,发现没有定义,接着去cat的原型对象上找,cat的原型对象这里已经被我们改成了People实例,那就是去People实例上去找。先找People的实例属性,发现有type,(如果实例属性上面没有type,就去People的原型对象上去找)这个查找就是这么一级一级的往上查找。


我们可以通过原型链的方式,实现 Cat继承 People 的所有属性和方法。总结来说:就是当重写了Cat.prototype指向的原型对象后,实例的内部指针也发生了改变,指向了新的原型对象,然后就能实现类与类之间的继承了。

你可能感兴趣的:(构造函数,原型对象,实例对象,原型链之间的关系)