对原型链相关的知识的梳理

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

 

posted on 2017-10-11 19:22  小菜园的菜  阅读(226)  评论(0编辑  收藏  举报