徹底理解什么是原型鏈,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>

  

**

 跟到寫一遍你就懂了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM