JavaScript的繼承方式

JavaScript的繼承方式

繼承是面向對象編程中又一非常重要的概念,JavaScript支持實現繼承,不支持接口繼承,實現繼承主要依靠原型鏈來實現的!下面就來介紹下javascript存在的繼承方式!

原型鏈:

原型鏈繼承基本思想就是讓一個原型對象指向另一個類型的實例。

JavaScript的繼承方式

代碼定義了兩個類型SuperType和SubType,每個類型分別有一個屬性和一個方法,SubType繼承了SuperType,而繼承是通過創建SuperType的實例,並將該實例賦給SubType.prototype實現的

實現的本質是重寫原型對象,代之以一個新類型的實例,那麼存在SuperType的實例中的所有屬性和方法,現在也存在於SubType.prototype中了

我們知道,在創建一個實例的時候,實例對象中會有一個內部指針指向創建它的原型,進行關聯起來,在這裡代碼 SubType.prototype = new SuperType() ,也會在SubType.prototype創建一個內部指針,將SubType.prototype與SuperType關聯起來

所以instance指向SubType的原型,SubType的原型又指向SuperType的原型,繼而在instance在調用getSuperValue()方法的時候,會順著這條鏈一直往上找

添加方法:

在給SubType原型添加方法的時候,如果,父類上也有同樣的名字,SubType將會覆蓋這個方法,達到重新的目的。 但是這個方法依然存在於父類中

記住不能以字面量的形式添加,因為,上面說過通過實例繼承本質上就是重寫,再使用字面量形式,又是一次重寫了,但這次重寫沒有跟父類有任何關聯,所以就會導致原型鏈截斷

JavaScript的繼承方式

問題:

單純的使用原型鏈繼承,主要問題來自包含引用類型值的原型。

JavaScript的繼承方式

在SuperType構造函數定義了一個colors屬性,當SubType通過原型鏈繼承後,這個屬性就會出現SubType.prototype中,就跟專門創建了SubType.prototype.colors一樣,所以會導致SubType的所有實例都會共享這個屬性,所以instance1修改colors這個引用類型值,也會反映到instance2中

借用構造函數:

此方法為了解決原型中包含引用類型值所帶來的問題

這種方法的思想就是在子類構造函數的內部調用父類構造函數,可以藉助apply()和call()方法來改變對象的執行上下文

JavaScript的繼承方式

在新建SubType實例是調用了SuperType構造函數,這樣以來,就會在新SubType對象上執行SuperType函數中定義的所有對象初始化代碼

結果,SubType的每個實例就會具有自己的colors屬性的副本了

傳遞參數:

藉助構造函數還有一個優勢就是可以傳遞參數

JavaScript的繼承方式

組合繼承(原型鏈+構造函數)

組合繼承是將原型鏈繼承和構造函數結合起來,從而發揮二者之長的一種模式

思路就是使用原型鏈實現對原型屬性和方法的繼承,而通過借用構造函數來實現對實例屬性的繼承

這樣,既通過在原型上定義方法實現了函數複用,又能夠保證每個實例都有它自己的屬性

JavaScript的繼承方式

這種模式避免了原型鏈和構造函數繼承的缺陷,融合了他們的優點,是最常用的一種繼承模式

原型式繼承:

藉助原型可以基於已有的對象創建新對象,同時還不必因此創建自定義類型

JavaScript的繼承方式

在object函數內部,先創建一個臨時性的構造函數,然後將傳入的對象作為這個構造函數的原型,最後返回這個臨時類型的一個新實例

本質上來說,object對傳入其中的對象執行了一次淺複製

JavaScript的繼承方式

這種模式要去你必須有一個對象作為另一個對象的基礎

在這個例子中,person作為另一個對象的基礎,把person傳入object中,該函數就會返回一個新的對象

這個新對象將person作為原型,所以它的原型中就包含一個基本類型和一個引用類型

所以意味著如果還有另外一個對象關聯了person,anotherPerson修改數組friends的時候,也會體現在這個對象中

相關推薦

推薦中...