• 解析原型链


    首先,创建一个构造函数:

    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();

      结果肯定是:吃  吃

    但是:这两个方法不是同一个方法

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

    这是为什么呢?

      每个实例对象都有自己的eat方法,而这个eat方法不是共享的

    如果我要创建100个对象,方法的实现是一样的,但却不能共享,岂不是很浪费空间?

    天无绝人之路,通过原型的方式是可以解决的:

      原型添加方法: 

    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;

    总结原型链:

      

  • 相关阅读:
    详解实现Android中实现View滑动的几种方式
    一起写一个Android图片轮播控件
    Java核心技术点之多线程
    深入了解整数在计算机内部的表示
    Java核心技术点之接口
    Java核心技术点之内部类
    配置resin web方式部署项目
    rsa加密算法,前后端实现。
    引用百度bcebos jar 503问题
    HashMap get()返回值问题
  • 原文地址:https://www.cnblogs.com/qyuan/p/9761075.html
Copyright © 2020-2023  润新知