<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里面的方法。