面試中常用的__proto__,prototype和原型鏈,你都了解了嗎?


上一篇隨筆主要講了變量提升的問題,今天我們來講講很多前端er在初期很長一段時間內都沒有完全搞明白的原型鏈和構造函數。

1,什么是構造函數

  那么要講到構造函數,必須要有一個函數,所以我們建立一個函數

    

function Person(){}

 ok,既然是構造函數,那么久要有參數和返回值 

Person = function(name,age,force){
          this.name = name;
          this.age = age;    
          this.force = force;
}

 一個函數就出來了,接下來我們來看一下這個Person的__proto__和prototype

Person.prototype    //Object {constructor:function(name,age,force),__proto__:Object}
Person.__proto__ //function(){}

  好的,我們的構造函數完成了,現在我們來通過構造函數創建一個對象

var mike = new Person('mike',23,'strong');
mike //Person {name: "mike", age: 23, force: "strong"}
mike.prototpe //undefined
mike.__proto__ //Object {constructor:function(name,age,force),__proto__:Object}

  在上面2段代碼,我們可以發現很多,仔細觀看mike.__proto__和Person.prototype,是不是發現,這兩者其實是一個東西,我們待會驗證一下,並且發現mike.prototype是undefined

alert(mike.__proto__ === Person.prototype)    //true

  這樣我們大概就了解了,構造函數new Person()發生時候的一個過程

  創建mike對象;

  mike.__proto__ = Person.prototype;  

  Person.call(mike,'mike',23,'strong');

2,__proto__和prototype

  __proto__按照定義來講,是對象自帶的一個屬性,這個__proto__它本身又是一個對象,__proto__的屬性,可以被mike讀取到,但不會顯示在mike對象里,當然__proto__對象中的屬性讀取優先級要低於mike本身

  而prototype呢,則是函數的一個自帶屬性,其中prototype又有兩個元素,1,constructor指向函數本身,2,__proto__同對象中的__proto__

  構造函數在創建對象是最大的特點就是會把自身的prototype按值傳遞給被構造對象的__proto__,因為prototype可以當做對象來看,所以是按引用傳遞//糾正上次的一個錯誤

  暫時我知道的prototype的作用,就是在構造對象時,將自身的prototype(引用)傳遞給新函數的__proto__

3,原型鏈

  這里我可以舉個例子

1 mike    //Person {name: "mike", age: 23, force: "strong"};
2 mike.__proto__face = 'handsome';
3 mike    //Person {name: "mike", age: 23, force: "strong"}
4 mike.face    //'handsome'

  mike對象中沒有face屬性,所以往mike.__proto__中找face,找到了,顯示出來,找不到的話,往mike.__proto__.__proto__中找face,如此往復,直到某一個__proto__返回null

4,多次繼承

  

function One(){
    this.sayOne = function(){
        alert('nameOne');     
     }
}
function    Two(){};
Two.prototype = new One();
Two.prototype.sayTwo = function(){
    alert('nameTwo');
}
var say = new Two();
say.sayOne()    //‘nameOne’
say.sayTwo()    //‘nameTwo’
two.prototype  //one(sayOne:function(){},sayTwo:function(){})

  

  原理很簡單 Two.prototype = new One(); 這一步得到 Two.prototype.__proto__ = One.prototype;

  say.__proto__ = Two.prototype;

  所以say.__proto__.__proto__ = One.prototype;

  所以say.sayTwo = say.__proto__.sayTwo = Two.prototype.sayTwo ;

    One.call(Two.prototype);

    say.sayOne = say.__proto__.sayTwo = Two.prototype.sayOne;

  要完成多次繼承,只要將上一層的屬性實例化到下一層的prototype即可,因為prototype是可以作為對象的__proto__直接使用的!


免責聲明!

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



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