Javascript重溫OOP之原型與原型鏈

prototype原型對象

每一個函數都有一個默認的prototype屬性,其實際上仍是一個對象,若是被用在繼承中,姑且叫作原型對象。函數

在構造函數中的prototype中定義的屬性和方法,會被建立的對象所繼承下來。舉個栗子:spa

function F(){}
F.prototype.work = function(){
    console.log('F is working..');
};
var f = new F();
f.work(); // F is working..

當你建立函數時,JS會爲這個函數自動添加 prototype 屬性,值是空對象。而一旦你把這個函數看成構造函數( constructor )調用(即經過 new 關鍵字調用),那麼JS就會幫你建立該構造函數的實例,實例繼承構造函數 prototype 的全部屬性和方法(實例經過設置本身的 __proto__ 指向承構造函數的 prototype 來實現這種繼承)。prototype

神祕的__proto__

JS的對象中都包含了一個__proto__屬性,其指向的是建立該對象時的構造函數的原型對象prototype。code

clipboard.png

從上面的輸出結果看出,f.__proto__指向了其構造函數F的prototype,而F.prototype自己也是一個對象,其內部也有__proto__屬性,其指向的是Object.prototype,直到最後Object.prototype指向null,這條原型鏈才結束。對象

所以,__proto__這個神祕的屬性纔是原型鏈造成的真正緣由。繼承

原型鏈

因爲原型對象自己也是對象,根據上邊的定義,它也有本身的原型,而它本身的原型對象又能夠有本身的原型,這樣就組成了一條鏈,這個就是原型鏈,JavaScritp引擎在訪問對象的屬性時,若是在對象自己中沒有找到,則會去原型鏈中查找,若是找到,直接返回值,若是整個鏈都遍歷且沒有找到屬性,則返回undefined。原型鏈通常實現爲一個鏈表,這樣就能夠按照必定的順序來查找。ip

下面是一張經典的圖:原型鏈

clipboard.png

從上圖看出:原型

  1. Object.prototype是頂級對象,全部對象都繼承自它。it

  2. Function 繼承 Function 自己, Function.prototype 繼承 Object.prototype

  3. Function.prototypeFunction.__proto__ 都指向 Function.prototype

  4. Object.prototype.__proto__ === null ,說明原型鏈到 Object.prototype 終止。

相關文章
相關標籤/搜索