JS--繼承(原型繼承)

繼承是很多OO語言中都支持的,基本上都支持兩種繼承方式:接口繼承和實現(xiàn)繼承。接口繼承只繼承方法名,實現(xiàn)繼承則繼承實際的方法。ECMAScript中無法實現(xiàn)接口繼承,只支持實現(xiàn)繼承的方式,這主要是依靠原型鏈來實現(xiàn)的。

原型鏈實現(xiàn)繼承的主要方式,是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。實現(xiàn)原型鏈有一種基本模式,其代碼大致如下:?

這里我們可以看到定義了兩個類型SuperType和SubType,SubType繼承SuperType的方式是將SuperType的實例對象賦值給了SubType的原型上,實現(xiàn)的本質(zhì)是重寫了SubType的原型對象,帶之以一個新類型的實例。SubType的prototype現(xiàn)在被賦值為SuperType的實例對象,SuperType的實例對象中的__proto__指向的是SuperType的原型對象,SuperType的原型對象中又有指針指向的是SuperType的構(gòu)造函數(shù),這樣SubType的prototype最終也會指向SuperType的原型對象,這樣就完成了原型鏈繼承。但是記住,所有函數(shù)的默認(rèn)原型都是Object的實例

如何確定原型和實例之間的關(guān)系?

我們可以通過兩種方式進(jìn)行卻,第一種是利用instanceof操作符,利用它可以測試實例和原型鏈中出現(xiàn)的構(gòu)造函數(shù),結(jié)果是返回true,例如:


第二種是利用isPrototypeOf(),只要原型鏈中出現(xiàn)過的原型,都可以說是該原型鏈派生的實例的原型,同樣的也會返回TRUE:


使用原型鏈進(jìn)行繼承確實很方便,但是不免會出現(xiàn)一些問題,問題之一就是包含引用類型值得原型,因為包含引用類型值得原型屬性會被所有實例共享,所以之前我們說屬性需要定義在構(gòu)造函數(shù)中,而不是定義在原型上面,但是通過原型進(jìn)行繼承,原型實際會變成另一個類型的實例,于是原先的實例屬性也就順理成章的變成了現(xiàn)在的原型屬性了。


如上可以看到,SuperType定義了一個構(gòu)造函數(shù),包含一個color屬性(數(shù)組,引用類型),

SuperType的每個實例都會包含一個color屬性,當(dāng)SubType通過原型繼承了SuperType的實例,實際上SubType.prototype也就成為了SuperType的一個實例,因此他也有了一個自己的color屬性。但是結(jié)果是SubType的所有實例都會共享這一個color屬性,所以看到后面對color的更改會反應(yīng)到SubType的所有實例中。

問題二是創(chuàng)建子類型的實例時,不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù),實際上應(yīng)該是沒有辦法在不影響所有對象實例的情況下,給父類的構(gòu)造函數(shù)傳遞參數(shù)。所以實踐中很少會單獨使用原型鏈。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容