对原型链相关的知识的梳理
<script>
function Obj(uName,uAge){
this.name=uName;
this.age=uAge;
this.fn_1=function(){
alert(this.name+','+this.age);
}
}
Obj.prototype.fn_1=function(){
alert(this.age+','+this.name)
}
var test=new Obj('小红',23);
test.fn_1();
</script>
在上段代码中,
首先有一个构造函数Obj,
通过代码可知,在构造函数Obj中有有两个属性name与age,有一个方法fn_1。
在每个函数中,都有会有一个隐藏的属性,叫做prototype即原型属性,如下图:

Obj的原型属性prototype指向的则是Obj的原型对象,即Obj.prototype。
Obj.prototype.fn_1=function(){ alert(this.age+','+this.name) }
在代码中通过原型属性在Obj的原型对象里面添加了一个fn_1的方法,如下图:

var test=new Obj('小红',23);
通过构造函数Obj声明了一个叫做test的对象,对象参数为‘小红’,23.
在这个被声明的test中,是没有构造函数Obj中的原型属性prototype的,
只有一个隐式原型_proto_,
而这个隐式原型_proto_是指向其构造函数的原型对象的,即Obj.prototype,如下图:

最后test.fn_1( )调用函数,由于在原型链中存在一个就近原则,即:
若对象中没有,则顺着原型链向上一级一级查找,由于对象中存在fn_1,所以执行对象中的fn_1.

将构造函数中的方法注释
<script>
function Obj(uName,uAge){
this.name=uName;
this.age=uAge;
// this.fn_1=function(){
// alert(this.name+','+this.age);
// }
}
Obj.prototype.fn_1=function(){
alert(this.age+','+this.name)
}
var test=new Obj('小红',23);
test.fn_1();
</script>
这样在构造函数与对象中都不存在fn_1了

这样在调用函数时只能通过隐式原型_proto_向上查找,找到了在原型对象上的fn_1,并执行,执行结果

有结果可知,执行了在原型对象上的fn_1.
已知,每个对象上都存在_proto_隐式原型,那么可以知道,在Obj.prototype原型对象上也存在一个隐式原型_proto_,
那这个隐式原型指向哪儿呢?
构造函数的隐式原型_proto_指向Object.prototype,即Object的原型对象。
在默认情况下,所有原型对象都会自动获得一个constructor属性,该属性包含一个指向prototype属性所在的函数。所以如下图所示:

在Object的原型对象中也存在_proto_隐式原型,不过该隐式原型指向为空。
就这样,通过原型链,把函数环环相扣,使声明的函数Obj也能够调用Object里面的方法。
浙公网安备 33010602011771号