web前端——原型链学习研究总结

首先来看一段代码:

<script>
    Function.lol = "迅捷提摸";
    Function.prototype.lol = "麦田炮手";
    Object.lol = "卡特琳娜";
    Object.prototype.lol = "抱走萝莉";

    function Show(){
        this.lol = "寒冰艾稀";
    }
    Show.prototype.lol = "漫天肥羽";

    var show = new Show();
    console.log(show.lol);
    /* 
        可以把Show对象看成是一个人,而 lol 可以比喻成一件衣服。
        现在天冷了,我们需要找一件波丝登穿到身上:console.log(show.lol)
        首先看看自己身上是不是已经穿上这件波丝登了:this.lol
        发现自己身上已经穿着波丝登羽绒服了:this.lol = "寒冰艾稀",那么就确定是这件衣服了。
        如果发现自己身上没穿羽绒服:this.lol = null或者没有定义。
        那么就在自己房间找一找:Show.prototype.lol = "漫天肥羽";
        如果自己的房间也没有,Show.prototype.lol = null,或者没有定义。
        那么就去自己爸爸身上找一找,看看不是爹给穿了:Object.lol。
        发现自己的爹穿不上自己的衣服,在爹身上找根本就是脑子进屎了,应该在爹的房间找才对:Object.prototype.lol
        爹房间也没有,还是去爷爷房间找一下吧:Function.prototype.lol = "麦田炮手";
        如果在爷爷的房间也没找到,说明是自己根本没有羽绒服。
     */
     /* 
         另外,每一个对象身上还有一个constructor属性,这个属性其实是该对象本身自己
         就跟去服装店里买衣服,拿了一块镜子一样,镜子中的自己就是自己,而这个constructor就是
         自己手中拿着的镜子。
      */
      console.log(typeof show.constructor);//结果类型是function
      console.log(Show === show.constructor);//结果为true
</script>

先说一下这段代码找值的优先级和方式:this.lol   =>  Show.prototype.lol  =>  Object.prototype.lol  =>  Function.prototype.lol 

为什么会出现这种情况,这就和原型链有关系了。

原型链:js代码在原型上找值的链子。

原型:原型也是对象,可以简单的理解为一个构造函数的prototype。

通过控制台打印的信息,我们可以看到,在构造函数Show的原型上面,有一个prototype属性,而在我们创建的实例对象show的原型上面有我们定义好的属性lol和系统提供的__proto__属性

接着向下看

我们可以看到,原型上面的prototype属性和实例对象上面的__proto__属性是一样的,所以说,实例对象上的__proto__属性就是原型上的prototype属性,它们都包含一个constructor属性对象。

下面看constructor的指向问题。

可以看到,这个constructor其实就是我们的构造函数Show,和我们最初看到的Show是一样的。

从这里我们可以看出来,构造函数、原型、和实例对象,它们三个像是一个三角形的关系。

上面这副图就是原型链的基本关系,下面我们在prototype上面添加一个方法,并创建两个实例对象。

我们发现,通过创建实例时传入的值,只能被具体创建的实例所共有,而通过构造函数的prototype添加的方法可以被所有的实例共享。

原型与Object的关系:

在构造函数的prototype上面,还有一个__proto__属性对象,它指向的是Object的prototype。

通过开始的例子我们知道,实例对象的__proto__指的就是构造函数的prototype,这里我们打印的obj就是Object的实例,里面的__proto__就是Object.prototype。里面也有一个constructor,指向的是Object构造函数。只不过Object.prototype上面没有__proto__,但是可以打印出来,结果是null。可以理解为Object.prototype.__proto__指向null,就是下面就没有了。

Function原型链:

通过上面的一些测验,可以知道,实例对象的__proto__就是构造函数的prototype。但是在构造函数上面也有一个__proto__

这个东西是什么呢?点开这个__proto__可以看到里面也有一个constructor属性,而这个constructor是指向Function的。所以,我们就可以得出一个结论是:构造函数的__proto__就是Function的prototype,Function.prototype.constructor就是Function这个构造函数。那么,我们所自定义的构造函数(比如Show)和系统提供的构造函数都是Function的实例,相当于:var Function = new Function();

我们把这个Function给打印出来,看看它身上都有什么东西。

Function也有prototype和__proto__属性,但是发现它们两个是同一个东西,所以说,Function.__proto__就是Function.prototype

在Fcuntion的prototype中也有一个__proto__,指向的也是Object.prototype。

所以,整个原型链的流程就是:

猜你喜欢

转载自blog.csdn.net/xishaoguo/article/details/93484193