1.构造函数,原型对象,实例对象三者之间的关系
每创建一个函数,该函数都会自动带有一个prototype属性。该属性是一个指针,指向一个对象,该对象称之为原型对象(后期我们可以使用这个原型对象帮助我们在js中实现继承)。
原型对象上默认有一个属性constructor,该属性也是一个指针,指向其相关联的构造函数。
通过调用构造函数产生的实例对象,都拥有一个内部属性,指向了原型对象。其实例对象能够访问原型对象上的所有属性和方法。
总结:三者的关系是,每个构造函数都有一个原型对象,原型对象上包含着一个指向构造函数的指针,而实例都包含着一个指向原型对象的内部指针。通俗的说,实例可以通过内部指针访问到原型对象,原型对象可以通过constructor找到构造函数。示例:
function People(){
this.type='人'
}
People.prototype.showType=function(){
alert(this.type);
}
var person=new People(); //调用原型对象上面的方法
person.showType();//最后结果弹框弹出人
People.prototype.constructor==People;//返回true
以上代码定义了一个构造函数People(),People.prototype指向原型对象,其自带属性construtor又指回了People,即People.prototype.constructor==People.实例对象person由于其内部指针指向了原型对象,所以可以访问原型对象上的showType方法。
记住People.prototype只是一个指针,指向的是原型对象,利用这个指针可以帮助我们实现js继承
2.原型链
在第一部分我们说到,所有的实例都有一个内部指针指向他的原型对象,并且可以访问到原型对象上的所有属性和方法。person实例对象指向了People的原型对象,可以访问People原型对象上的所有属性和方法。如果People原型对象变成了某一个类的实例dog,这个实例又会指向一个新的原型对象DOG,那么person此时能访问dog的实例属性和DOG原型对象上的所有属性和方法了。同理新的原型对象DOG碰巧有事另外一个对象的实例cat,这个对象实例指向原型对象CAT,那么person就能访问cat的实例属性和CAT原型上的属性和方法了。
function People(){
this.type='人'
}
People.prototype.showType=function(){
alert(this.type);
}
function Cat(){
this.sex='女';
this.age=4;
}
Cat.prototype=new People();
var c=new Cat();
console.log('大家好,我的种类是:'+c.type+",我的年龄是:"+c.age+",我的性别是:"+c.sex);
//输出结果:
//大家好,我的种类是:人,我的年龄是:4,我的性别是:女
//c.type是People上面定义的type
以上代码,首先先定义了People构造函数,通过new People()得到实例,会包含一个实例对象type和一个原型属性showType。另外定义一个Cat构造函数,然后情况发生变化,本来构造函数Cat的prototype会执行cat的原型对象,但是我们这里稍有改变,将Cat构造函数的prototype指向了People实例对象覆盖了Cat的原型对象。当Cat的实例对象cat去访问type属性时,js首先在cat实例属性中查找,发现没有定义,接着去cat的原型对象上找,cat的原型对象这里已经被我们改成了People实例,那就是去People实例上去找。先找People的实例属性,发现没有type,最后去People的原型对象上去找,终于找到了。这个查找就是这么一级一级的往上查找。
function People(){
this.type='人'
}
People.prototype.showType=function(){
alert(this.type);
}
function Cat(){
this.sex='女'; this.age=4;this.type='花猫';
//如果这里定义了type属性,就不会层级查找,最后在People找到该属性
}
Cat.prototype=new People();
var c=new Cat();
console.log('大家好,我的种类是:'+w.type+",我的年龄是:"+w.age+",我的性别是:"+w.sex);
//输出结果:
//大家好,我的种类是:花猫,我的年龄是:4,我的性格是:女
我们可以通过原型链的方式,实现 Woman继承 People 的所有属性和方法。总结来说:就是当重写了Woman.prototype指向的原型对象后,实例的内部指针也发生了改变,指向了新的原型对象,然后就能实现类与类之间的继承了。