解析原型链

首先,建立一个构造函数:程序员

function Person(name,age){
        this.name=name;
        this.age=age;
        this.eat=function(){
            console.log("吃");
        }
    }

接着,咱们实例化两个对象:浏览器

     var stu1 = new Person("小明",20);
     var stu2 = new Person("小花",30);

咱们调用两个对象的eat方法:函数

    stu1.eat();
    stu2.eat();

  结果确定是:吃  吃this

可是:这两个方法不是同一个方法spa

   console.log(stu1.eat===stu2.eat);//false

这是为何呢?prototype

  每一个实例对象都有本身的eat方法,而这个eat方法不是共享的3d

 

若是我要建立100个对象,方法的实现是同样的,但却不能共享,岂不是很浪费空间?code

天无绝人之路,经过原型的方式是能够解决的:
对象

  原型添加方法: blog

Person.prototype.eat=function(){
        console.log("吃东西");
    }

  此时构造函数和原型对象中都有eat方法,默认先找构造函数,构造函数没有找原型对象,原型对象没有undefind

  咱们删掉以前构造函数中的eat(),此时:

   console.log(stu1.eat===stu2.eat);//true

  原型的做用:解决数据共享,节省内存空间

那么原型对象是什么呢?

  Person() 是一个构造函数,咱们经过console.dir(Person),查看他的详细信息,

  

  发现该构造函数有一个属性prototype,该属性也是一个对象,标准属性,是给程序员使用的,这个属性叫作原型对象。

 

  stu1是一个实例对象,咱们经过console.dir(stu1),查看他的详细对象

  

  发现该实例对象有一个属性__proto__,该属性也是一个对象,非标准属性,给浏览器使用的,这个属性叫作原型对象。

从stu1的详细中看到他并无eat()方法,那么他是如何访问这个方法的呢?

  咱们打开prototype这个属性:

  

  实例对象中没有eat(),构造函数中的prototype中有eat()

  由此推出:实例对象的__proto__的指向和该实例对象所在的构造函数的prototype的指向相同,

       那么实例对象就能够直接访问prototype中的方法了

下面图中的construtor是什么?

                                                                  

  上图实例对象的__proto__中的constructor就是该实例对象所在的构造函数               构造函数中的prototype中的constructor指向的是原型对象所在的构造函数

而构造函数、实例对象、原型对象三者之间的关系是什么呢?

  (1)实例对象是经过构造函数建立的

  (2)构造函数中prototype叫原型对象

  (3)构造函数中的prototype中有constructor叫构造器,指向的是该原型对象所在的构造函数

  (4)实例对象中__proto__叫原型对象

  (4)实例对象中__proto__指向的是该实例对象所在的构造函数的prototype

 

 

说到这里咱们就要开始推导原型链了:

  能够这么理解:原型链就是实例对象和原型对象之间的一种关系

  咱们说:构造函数中有prototype,实例对象中有__proto__

      实例对象的__proto__指向的是该实例对象所在的构造函数中的prototype

  换句话说就是:对象的__proto__指向的确定是某个函数的prototype

  往下看:

  

  构造函数中prototype是对象,这个prototype中有__proto__也是对象,那么这个__proto__指向的是谁呢?

    它指向的确定是某个构造函数的prototype

    此时,观察它的构造器的指向----是Object()

    那么得出结论:    

   Person.prototype.__proto__===Object.prototype//true

  

    继续观察Person():

    

    咱们以前说构造函数中有prototype,可是我此时也发现了构造函数中有__proto__,

    既然看到了__proto__,逆推思想:说明这个函数实际上也是一个对象(由于对象中有__proto__);

    因此Person()的__proto__指向的确定是其构造函数的prototype;

    对象是经过构造函数建立的,那么Person()的构造函数又是谁呢?

      看Person.__proto__.constructor的指向--------Function()

    得出结论:   

   Person.__proto__===Function.prototype//true

    这个时候咱们知道了:

      js中的函数实际上都是经过Function这个构造函数来建立的(来实例化出来的);

    接下来,咱们往下深挖,Function

    

    由此推出:  

   Function.prototype.__proto__===Object.prototype//true

    

    由此推出:

   Function.__proto__=== Function.prototype;//true

    

    接下来,还有最后一个Object

    

      由此推出:   

    Object.__proto__=== Function.prototype;//true

      

      

    Object的prototype中没有__proto__   

   Object.prototype.__proto__ === null;

 

总结原型链:

  

相关文章
相关标签/搜索