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

上一篇隨筆主要講了變量提高的問題,今天咱們來說講不少前端er在初期很長一段時間內都沒有徹底搞明白的原型鏈和構造函數。javascript

1,什麼是構造函數前端

  那麼要講到構造函數,必需要有一個函數,因此咱們創建一個函數java

    

function Person(){}

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

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

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

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

  好的,咱們的構造函數完成了,如今咱們來經過構造函數建立一個對象spa

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是undefinedprototype

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

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

  建立mike對象;對象

  mike.__proto__ = Person.prototype;  blog

  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__直接使用的!

相關文章
相關標籤/搜索