JavaScript中的繼承和原型
JavaScript是基于原型的面向對象語言,沒有類的概念,我們先來說說原型prototype。
每個對象都有原型,原型是一種對象,修改對象的原型,可以影響所有由本對象派生的對象,但是如果僅僅修改本對象,并不會影響已經創建的實例的原型。因為 每個對象和原型都有一個原型,對象的原型指向對象的父原型,而父原型又指向父原型的父原型,這種通過原型層層連接起來的關系稱為原型鏈,這條鏈的末端一般 總是默認的對象原型。
原型中讀的是從原型鏈上讀,寫是往自己里面寫。
<script type="text/javascript"> function load() { function obj1() {//對象obj1 } function obj2() {//對象obj2 } obj2.prototype = new obj1(); //obj1賦值給obj2的原型 Object.prototype.foo = function () { alert("object"); //Object對象foo函數彈出object } testobj = new obj2(); //obj2賦值給測試對象testobj testobj.foo(); //執行測試對象的foo函數 obj1.prototype.foo = function () { alert("obj1"); //對obj1的原型函數foo重新賦值 } testobj.foo(); //在此執行測試對象的foo函數 } window.onload = load; </script>運行結果:
結果分析:
我們先創建了對象obj1和obj2,把obj1的原型賦值給obj2,再 Object的原型中添加函數foo顯示‘Object’,再把obj2賦值給測試對象testobj,執行testobj中的foo,我們發現實際執行 的是Object中的foo,為什么?因為讀取的時候,一次從testobj---obj2---obj1---Object讀取,直到Object方能 讀取到foo,所以說讀是從原型鏈從淺入深讀取。然后我們修改obj1的原型,使之也有foo函數,再次執行testobj的foo,我們發現實際執行的 是obj1的foo,可見對obj1寫foo的時候是直接寫到自己的原型上的。如圖:
繼承是簡單的復制
<script type="text/javascript"> function load() { var father = new Object();//創建父對象 var son = new Object();//創建子對象 father.name = function () { alert('dad');//彈出dad } son.name = function () { alert('son');//彈出son } son.name = father.name; //把父對象的姓名賦值給子對象 father.name = function () { alert('new dad'); //覆寫父對象姓名為new dad } father.name(); //彈出父對象的姓名 son.name();//彈出子對象的姓名 } window.onload = load;//把load函數添加到頁面加載上 </script>運行結果:
結果分析:
我們創建父對象father和子對象son,定義father的name為 “dad”,son的name為“son”,再把father的name賦值給son,重新定義father的name為“new dad”。執行father的name,顯示為“new dad”,這個在我們意料之中;而執行son的name卻是“dad”而非“new dad”,可見繼承屬性,僅僅是復制父對象的屬性,而不是引用。
用了兩個簡單的實例說明了一下javascript中的原型和繼承,對于其更深層次的原型鏈和構造器,因為所學有限,等待以后的補充學習后繼續討論。