繼承
是面向對象編程語言中的一個重要的概念,繼承能夠使得子類具備父類的屬性和方法或者從新定義、追加屬性和方法等。可是在Javascript中沒有類
的概念,是基於原型的語言,因此這就意味着對象能夠直接從其餘對象繼承。javascript
Ecmascript中描述了原型鏈的概念,並將原型鏈做爲繼承的主要方法,主要是想利用原型鏈讓一個引用類型繼承另外一個引用類型的屬性和方法。java
構造函數、原型對象、實例之間的關係是:每一個構造函數都有一個原型對象,每一個原型對象中都有一個指針指向了該構造函數(constructor
):chrome
function A(){} A.prototype.constructor == A //true
而實例中有一個內部的指針指向了原型對象([[prototype]]
),在chrome,firefox等幾款瀏覽器的JS引擎中加入了__proto__
來訪問原型對象[[prototype]]:編程
function B(){} var b = new B(); b.__proto__ == B.prototype // true
當在實例對象中查找某一屬性或方法的時候,會優先查找當前實例中是否包含該屬性,若是未找到,便會在該實例的原型對象中查找,若是還未找到,就會再沿着原型對象中的內部原型指針繼續往上層原型對象查找,層層遞進,這樣就構成了所謂的原型鏈。瀏覽器
function SuperType() { this.peoperty = true; } SuperType.prototype.getSuperValue = function() { return this.property; } function SubType() { this.subproperty = false; } SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function() { return this.subproperty; } var instance = new SubType(); console.log(instance.getSuperValue()); //true
上面的代碼中SubType繼承了SuperType,這是經過將SuperType的實例賦給SubType.prototype實現的,本質是重寫了SubType的原型對象。編程語言
在Javascript中,全部引用類型都默認繼承了Object,同樣都是經過原型鏈來繼承的。因此全部函數的默認原型都是Object.prototype,所以默認原型內部都會有一個指向Object.prototype的指針,因此上面的代碼的原型鏈圖形的頂層應該還有一個Object:函數