JavaScript的繼承機制
JavaScript 不包含傳統的類繼承模型,而是使用 prototype 原型模型,雖然這經常被當作是 JavaScript 的缺點被提及,其實基於原型的繼承模型比傳統的類繼承還要強大。實現傳統的類繼承模型是很簡單,但是實現 JavaScript 中的原型繼承則要困難的多。由於 JavaScript 是唯一一個被廣泛使用的基於原型繼承的語言,所以理解兩種繼承模式的差異是需要一定時間的,今天我們就來了解一下原型和原型鏈。
一個關於繼承和實例化的例子
function Shape(){
this.x = 0;
this.y = 0;
}
Shape.prototype.area = function(){
...
}
function Circle(){
this.radius = 1;
}
Circle.prototype = new Shape();
Circle.prototype.area = function(){
...
}
Circle.prototype.constructor = Circle;
var cir = new Circle();
我的理解
JavaScript用function模擬class,一個function對象會自帶prototype屬性,這個屬性是JS實現面向對象的關鍵。
Circle是Shape的子類,是通過在Circle的prototype中放置一個Shape的實例來實現功能傳遞的。
通過new來創建實例,實例是object類型,無prototype屬性。Circle的所有實例都會共享同一份prototype,該prototype中包含Shape的一個實例,一處更改,處處更改。
注意將Circle的構造器指回Circle。
原型鏈 如果按目錄的形式來展開原型鏈,如下,cir作爲主目錄包含下面所有的內容。
~cir
~~radius
~~Circle.prototype(new Shape() & area)
~~~{x y area}
~~~Shape.prototype
~~~~area
~~~~Object.prototype
~~~~~{toString ...}
屬性查找
當查找一個對象的屬性時,JavaScript 會向上遍歷原型鏈,直到找到給定名稱的屬性爲止,到查找到達原型鏈的頂部,也就是 Object.prototype,但是仍然沒有找到指定的屬性,就會返回 undefined。屬性在查找的時候是先查找自身的屬性,如果沒有再查找原型,再沒有,再往上走,一直插到Object的原型上,所以在某種層面上說,用 for in語句遍歷屬性的時候,效率也是個問題。
hasOwnProperty
hasOwnProperty是Object.prototype的一個方法,他能判斷一個對象的某個屬性是否是自有屬性,而且hasOwnProperty是JavaScript中唯一一個在處理屬性時不查找原型鏈的函數。
但是hasOwnProperty可能會被輕易的覆蓋,所以有時爲了保險起見,要用Object的該方法,當然如果Object的方法也被更改就沒辦法了。