zoukankan      html  css  js  c++  java
  • 彻底理解什么是原型链,prototype和__proto__的区别以及es5中的继承

    再讲一遍好了(

    参考https://blog.csdn.net/cc18868876837/article/details/81211729

    https://blog.csdn.net/lc237423551/article/details/80010100

    Javascript中所有的对象都是Object的实例,并继承Object.prototype的属性和方法,也就是说,Object.prototype是所有对象的爸爸。

    首先,我们需要牢记两点__proto__constructor属性是对象所独有的;② prototype属性是函数所独有的。但是由于JS中函数也是一种对象,所以函数也拥有__proto__constructor属性,这点是致使我们产生困惑的很大原因之一。

    首先盗个图先:--》

    上图很复杂,先拆分一下

    第一,这里我们仅留下__proto__属性,它是对象所独有的,可以看到__proto__属性都是由一个对象指向一个对象,即指向它们的原型对象(也可以理解为父对象),那么这个属性的作用是什么呢?它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存在这个属性,则继续往父对象的__proto__属性所指向的那个对象(可以理解为爷爷对象)里找,如果还没找到,则继续往上找….直到原型链顶端null(可以理解为原始人。。。),此时若还没找到,则返回undefined(可以理解为,再往上就已经不是“人”的范畴了,找不到了,到此为止),由以上这种通过__proto__属性来连接对象直到null的一条链即为我们所谓的原型链。

    第二,接下来我们看prototype属性

    prototype属性,别忘了一点,就是我们前面提到要牢记的两点中的第二点,它是函数所独有的,它是从一个函数指向一个对象。它的含义是函数的原型对象,也就是这个函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象,由此可知:f1.__proto__ === Foo.prototype,它们两个完全一样。那prototype属性的作用又是什么呢?它的作用就是包含可以由特定类型的所有实例共享的属性和方法,也就是让该函数所实例化的对象们都可以找到公用的属性和方法。

    ******************************下面的例子来一遍你就更懂了

    <!doctype html>
    <html>
        <head>
            <meta charset="utf-8">
            <meta name="description" content="">
            <meta name="viewport" content="width=device-width, initial-scale=1">
    
            <script>
    
    
     // es5里面的类  
            
    
    //1.最简单的类
            // function Person(){
    
            //     this.name='张三';
            //     this.age=20;
            // }
            // var p=new Person();
            // alert(p.name);
    
    
    
    //2、构造函数和原型链里面增加方法
    
    
            // function Person(){
    
            //     this.name='张三';  /*属性*/
            //     this.age=20;
            //     this.run=function(){
    
            //         alert(this.name+'在运动');
            //     }
    
            // }
            // //原型链上面的属性会被多个实例共享   构造函数不会
            // Person.prototype.sex="男";
            // Person.prototype.work=function(){
            //     alert(this.name+'在工作');
            
            // }
            // var p=new Person();
            // // alert(p.name);
            // // p.run();
            // p.work();
    
    
    
    //3类里面的静态方法
    
    
            // function Person(){
    
            //     this.name='张三';  /*属性*/
            //     this.age=20;
            //     this.run=function(){  /*实例方法*/
    
            //         alert(this.name+'在运动');
            //     }
    
            // }
    
            // Person.getInfo=function(){
    
            //     alert('我是静态方法');
            // }
            // //原型链上面的属性会被多个实例共享   构造函数不会
            // Person.prototype.sex="男";
            // Person.prototype.work=function(){
            //     alert(this.name+'在工作');
    
            // }
            // var p=new Person();    
            // p.work();
    
            // //调用静态方法
            // Person.getInfo();
    
    
    
    // 4、es5里面的继承   对象冒充实现继承
    
    
        //    function Person(){
        //         this.name='张三';  /*属性*/
        //         this.age=20;
        //         this.run=function(){  /*实例方法*/
        //             alert(this.name+'在运动');
        //         }
    
        //     }      
        //     Person.prototype.sex="男";
        //     Person.prototype.work=function(){
        //          alert(this.name+'在工作');
    
        //     }
           
        //     //Web类 继承Person类   原型链+对象冒充的组合继承模式
    
        //     function Web(){
    
        //         Person.call(this);    /*对象冒充实现继承*/
        //     }
    
        //     var w=new Web();
        //    // w.run();  //对象冒充可以继承构造函数里面的属性和方法
    
        //     w.work();  //对象冒充可以继承构造函数里面的属性和方法   但是没法继承原型链上面的属性和方法
    
    
    
    
    // 5、es5里面的继承   原型链实现继承
    
        //    function Person(){
        //         this.name='张三';  /*属性*/
        //         this.age=20;
        //         this.run=function(){  /*实例方法*/
        //             alert(this.name+'在运动');
        //         }
    
        //     }      
        //     Person.prototype.sex="男";
        //     Person.prototype.work=function(){
        //          alert(this.name+'在工作');
    
        //     }
           
        //     //Web类 继承Person类   原型链+对象冒充的组合继承模式
    
        //     function Web(){
             
        //     }
    
        //    Web.prototype=new Person();   //原型链实现继承
        //    var w=new Web();
        //     //原型链实现继承:可以继承构造函数里面的属性和方法 也可以继承原型链上面的属性和方法
        //     //w.run();
    
        //     w.work();
    
    
    
    
    // 6、 原型链实现继承的 问题?
    
        //    function Person(name,age){
        //         this.name=name;  /*属性*/
        //         this.age=age;
        //         this.run=function(){  /*实例方法*/
        //             alert(this.name+'在运动');
        //         }
    
        //     }      
        //     Person.prototype.sex="男";
        //     Person.prototype.work=function(){
        //          alert(this.name+'在工作');
    
        //     }
           
        //    var p=new Person('李四',20);
        //    p.run();
    
    
    
    
    
    
        // function Person(name,age){
        //         this.name=name;  /*属性*/
        //         this.age=age;
        //         this.run=function(){  /*实例方法*/
        //             alert(this.name+'在运动');
        //         }
    
        // }      
        // Person.prototype.sex="男";
        // Person.prototype.work=function(){
        //         alert(this.name+'在工作');
    
        // }
           
          
        // function Web(name,age){
    
            
        // }
    
        // Web.prototype=new Person();
    
        // var w=new Web('赵四',20);   //实例化子类的时候没法给父类传参
    
        // w.run();
    
        // // var w1=new Web('王五',22);
    
    
    
    
    
    
    //7.原型链+对象冒充的组合继承模式
    
    
    //   function Person(name,age){
    //             this.name=name;  /*属性*/
    //             this.age=age;
    //             this.run=function(){  /*实例方法*/
    //                 alert(this.name+'在运动');
    //             }
    
    //     }      
    //     Person.prototype.sex="男";
    //     Person.prototype.work=function(){
    //             alert(this.name+'在工作');
    
    //     }
           
          
    //     function Web(name,age){
    
    //         Person.call(this,name,age);   //对象冒充继承   实例化子类可以给父类传参
    //     }
    
    //     Web.prototype=new Person();
    
    //     var w=new Web('赵四',20);   //实例化子类的时候没法给父类传参
    
    //     // w.run();
    //     w.work();
    
    //     // var w1=new Web('王五',22);
    
    
    
    
    
    
    //8、原型链+对象冒充继承的另一种方式
    
    
       function Person(name,age){
                this.name=name;  /*属性*/
                this.age=age;
                this.run=function(){  /*实例方法*/
                    alert(this.name+'在运动');
                }
    
        }      
        Person.prototype.sex="男";
        Person.prototype.work=function(){
                alert(this.name+'在工作');
    
        }
        
           
          
        function Web(name,age){
    
            Person.call(this,name,age);   //对象冒充继承  可以继承构造函数里面的属性和方法、实例化子类可以给父类传参
        }
    
        Web.prototype=Person.prototype;
    
        var w=new Web('赵四',20);   //实例化子类的时候没法给父类传参
    
         w.run();
        // w.work();
    
        // var w1=new Web('王五',22);
    
    
    
    
    
    
    
            </script>
    
        </head>
        <body>
         
        </body>
    </html>
    

      

    **

     跟到写一遍你就懂了

  • 相关阅读:
    S2-001 远程代码执行漏洞
    Struts2 devMode远程代码执行漏洞检测利用
    CVE-2017-12615(Tomcat PUT方法任意写文件漏洞)
    Medium | LeetCode 343 | 剑指 Offer 14- I. 剪绳子 | 动态规划
    Medium | 剑指 Offer 38. 字符串的排列 | 回溯
    Medium | 剑指 Offer 60. n个骰子的点数 | 动态规划
    Medium | 剑指 Offer 46. 把数字翻译成字符串 | 回溯
    Medium | 剑指 Offer 59
    Hard | LeetCode 239 | 剑指 Offer 59
    Medium | 剑指 Offer 35. 复杂链表的复制
  • 原文地址:https://www.cnblogs.com/myfirstboke/p/10449272.html
Copyright © 2011-2022 走看看