首頁 >web前端 >js教程 >關於JavaScript中原型繼承中的一點思考_javascript技巧

關於JavaScript中原型繼承中的一點思考_javascript技巧

WBOY
WBOY原創
2016-05-16 17:51:44821瀏覽

我們先來看一段傳統的繼承碼:

複製程式碼 程式碼如下:

//定義超類
function Father(){
this.name = "父親";
}
Father.prototype.theSuperValue = ["NO1","NO2"];
//定義子類別
function Child(){
}
//實作繼承
Child.prototype = new Father();
//修改共享陣列
Child.prototype.theSuperValue. push("修改");
//建立子類別實例
var theChild = new Child();
console.log(theChild.theSuperValue); //["NO1","NO2", "修改"]
//建立父類別實例
var theFather = new Father();
console.log(theFather.theSuperValue); //["NO1","NO2","修改" ]

透過上面的程式碼,我們注意到「加紅」的程式碼,子類別Child的原型物件是父類別Father的一個實例(new Father()),我們在這裡是呼叫new Father()物件中的theSuperValue屬性,因為new Father()物件中沒有此屬性(只有name屬性),因此會沿著原型鏈向它的原型物件(Father.prototype)中去找,找到後發現是一個數組,而且是引用類型,此時我們往此數組中添加一個字串“修改”。

  之後,我們新建了Child的實例物件theChild,當theChild呼叫theSuperValue屬性時,首先它自己裡面沒有此屬性,就會去它的原型物件(new Father)去找,可惜這裡也沒有,接著會到new Father()的原型中去找,OK,在Father.prototype中找到了這個數組,發現是["NO1","NO2","修改"]。

  再接著,我們建立了Father的實例物件theFather,同上,我們在Father.prototype中找到了這個引用類型的陣列["NO1","NO2","修改"]。 (當然,數組都是引用類型的!)

  透過上面的贅述,本來已經理解原型鏈概念的朋友覺得是廢話連篇,其實我也是呵呵,接下來我們再看一個相似的例子:
複製程式碼 程式碼如下:

//定義超類this.name = "父親";
}
Father.prototype.theSuperValue = ["NO1", "NO2"];
//定義子類別
function Child() {
}
//實作繼承
Child.prototype = new Father();
//修改共用陣列
Child.prototype.theSuperValue = ["我是覆蓋程式碼"]
//建立子類別實例
var theChild = new Child();
console.log(theChild.theSuperValue);
//建立父類別實例
var theFather = new Father() ;
console.log(theFather.theSuperValue);


我們看一下上面的程式碼,我用一種比較特別的紫色標註了此段程式碼與上段程式碼的小小區別,但結果卻發生了「巨大」變化,見下面的截圖:

  為什麼我說是巨大變化,是因為我們從「重用公共屬性」過渡到「覆蓋公共屬性,建立自己特色屬性」上來!我這裡是用陣列來示範的,其實第二種情況常常用在Function中,用子類別的方法來覆寫父類別的方法。


在第二段程式碼中,我們需要注意的是紫色程式碼前的「=」號,它是賦值運算子。如果我們對Child.prototype及new Father()物件呼叫這個賦值運算子時,我們就在這個物件上「新建」了一個屬性,當在下面的theChild實例上呼叫theSuperValue時,傳回的當然是新屬性值["我是覆蓋代碼"]。

  但當我們新建立一個父類別實例theFather物件時,呼叫該物件上的theSuperValue屬性,我們就會發現物件上並沒有​​啊,這是為什麼呢?因為我們剛剛涵蓋的是Father物件new Father();而不是Father類,所以,透過Fater()建構函數所創建的新物件theFather並不包含新建的屬性,當然,接下來的事情大家都明白,就是沿著原型鏈往上找,OK,在Father.prototype中找到了,就是我們一開始定義的那個陣列。

  透過上面兩個例子,我們在JS中使用原型提供的繼承功能時,尤其是利用子物件操作原型方法、物件時,切記「=」號賦值與引用呼叫這兩種不同的操作,因為他們會帶來完全不同的結果。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn