摘要:還有一個問題,就是不能在創(chuàng)建子類性時,像父類型的構(gòu)造函數(shù)傳遞參數(shù)。組合繼承將原型鏈和借用構(gòu)造函數(shù)組合到一起,發(fā)揮兩者之長的一張繼承模式,下面來看個例子。組合繼承最大的問題是無論在什么情況下,都會調(diào)用兩次父類型構(gòu)造函數(shù)。
繼承
繼承是面向?qū)ο笳Z言中特別重要的概念,js的繼承主要是靠原型鏈實現(xiàn)的。
原型鏈?。?!看到我給標(biāo)題打了三個嘆號嗎,這里真的很重要!這里真的很重要!這里真的很重要!js描述了原型鏈的概念,并將原型鏈做為實現(xiàn)繼承的主要方法,其基本思想是讓一個引用類型繼承另一個引用類型的屬性和方法??创a
function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function () { return this.property; } function SubType () { this.Subproperty = false; } SubType.prototype = new SuperType(); SuperType.prototype.getSubValue = function () { return this.subproperty; } var instance = new SubType(); console.log(instance.getSuperValue())
下面繼續(xù)上我的靈魂畫作:
話不多說,原理都在圖里,相信聰明的你們早就懂了。在上面的代碼中,我們沒有使用SubType默認(rèn)提供的原型,而是給它換了一個新原型。這個原型是父類的實例,新原型具有全部屬性和方法,現(xiàn)在也存在于子類的原型中了。
通過原型鏈,本質(zhì)上擴展了原型搜索機制。在instance.getSuperValue()調(diào)用會經(jīng)歷三個搜索步驟
搜索實例
搜索原型對象
搜索父類原型對象
一環(huán)一環(huán)向上搜索直到原型鏈末端才會停下來。但是我們子類上的valueOf這些方法是哪里來的呢?父類并沒有顯示聲明這些方法啊下面繼續(xù)上圖。
SubType繼承了SuperType,SuperType繼承了Object,當(dāng)調(diào)用instance.valueOf()方法時,實際上調(diào)用的是保存在Object.prototype中的方法。
原型鏈的問題原型鏈這么強大,同樣也會造成問題。最主要的問題來自于包含引用類型的原型。引用類型的原型屬性會被雖有實例共享,在通過原型來實現(xiàn)繼承時,原型會變成另一個類型的實例,原先的實例屬性也就順理成章變成來現(xiàn)在的原型屬性。
function SuperType () { this.colors = ["red", "blue", "green"]; } function SubType () { } SubType.prototype = new SuperType(); var instance1 = new SubType(); instance1.colors.push("black"); console.log(instance1.colors) var instance2 = new SubType(); console.log(instance2.colors)
還有一個問題,就是不能在創(chuàng)建子類性時,像父類型的構(gòu)造函數(shù)傳遞參數(shù)。所以我們一般很少多帶帶使用原型鏈。
借用構(gòu)造函數(shù)function SuperType () { this.colors = ["red", "blue", "green"]; } function SubType () { // 繼承了 SuperType SuperType.call(this); } var instance1 = new SubType(); instance1.colors.push("black"); console.log(instance1.colors); var instance2 = new SubType(); console.log(instance2.colors);
也可以傳遞參數(shù)
function SuperType (name) { this.name = name; } function SubType () { // 繼承了 SuperType SuperType.call(this, "李小花"); } var instance1 = new SubType(); console.log(instance1.name) 但是這樣問題也很明顯,方法只能定義在構(gòu)造函數(shù)中定義,定義在原型上的方法無法繼承。借用構(gòu)造函數(shù)的技術(shù)也很少使用。組合繼承
將原型鏈和借用構(gòu)造函數(shù)組合到一起,發(fā)揮兩者之長的一張繼承模式,下面來看個例子。
function SuperType (name) { this.name = name; } SuperType.prototype.sayName = function() { console.log(this.name) }; function SubType (name, age) { // 繼承了 SuperType SuperType.call(this, name); this.age = age; } SubType.prototype = new SuperType(); var instance1 = new SubType(); console.log(instance1.name)
寄生組合式繼承組合繼承是 js最常用的繼承模式。
組合繼承是最常用的繼承模式,但也不是沒有缺點。組合繼承最大的問題是無論在什么情況下,都會調(diào)用兩次父類型構(gòu)造函數(shù)。
function SuperType (name) { this.name = name; } SuperType.prototype.sayName = function() { console.log(this.name) }; function SubType (name, age) { // 繼承了 SuperType SuperType.call(this, name); //第二次調(diào)用 this.age = age; } SubType.prototype = new SuperType(); // 第一次調(diào)用 var instance1 = new SubType(); console.log(instance1.name)
我們不必為了指定子類型的原型調(diào)用超類型的構(gòu)造函數(shù),我們所需要的不過是超類型原型的一個副本而已。
function SuperType (name) { this.name = name; this.color = ["red", "blue", "green"]; } SuperType.prototype.sayName = function() { console.log(this.name); }; function SubType (name, age) { SuperType.call(this, name); this.age = age; } SubType.prototype = Object.create(SuperType.prototype); SubType.prototype.constructor = SubType
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83499.html
摘要:一面向?qū)ο缶幊袒A(chǔ)實踐通過對象的編程方式,可將實現(xiàn)生活中的一切事物以對象的形式表現(xiàn)出來。此時程序也將會報致命錯誤。屬性不可訪問或未定義,值判斷對象中的屬性不存在時,自動執(zhí)行該函數(shù)。屬性值未定義釋放對象中的不存在的屬性值時,自動執(zhí)行該函數(shù)。 一、PHP面向?qū)ο缶幊袒A(chǔ)實踐 二、PHP面向?qū)ο蟾呒壘幊虒嵺` 知識點:類的繼承、方法重寫、訪問控制、static關(guān)鍵字、final關(guān)鍵字、數(shù)據(jù)訪...
摘要:引言對于面向?qū)ο螅嘈糯蠹乙欢ú荒吧?。?chuàng)建對象面向?qū)ο蟮谝徊绞鞘裁创饎?chuàng)建對象。構(gòu)造函數(shù)優(yōu)于工廠模式也是在于它可以通過辨識出一類的對象。 引言 對于面向?qū)ο螅嘈糯蠹乙欢ú荒吧?。最近看了一些關(guān)于es6面向?qū)ο蟮闹R,正好通過這篇文章把關(guān)于面向?qū)ο蟮臇|西給串起來分享給大家。 什么是對象 很多人會鄙視我,說你這篇文章是騙騙剛?cè)胄械男∨笥训陌桑裁词菍ο笪疫€能不知道?罵我的吃瓜群眾先冷靜一下,...
摘要:中的和是一門很靈活的語言,尤其是。即然是面向?qū)ο蟮木幊陶Z言,那也是不可或缺的。在中,永遠(yuǎn)指向的是他的調(diào)用者。定義是存在于實例化后對象的一個屬性,并且指向原對象的屬性。我們在擴展的時候,同時父類也會有對應(yīng)的方法,這很顯然是一個很嚴(yán)重的問題。 javascript中的this和new javascript是一門很靈活的語言,尤其是function。他即可以以面向過程的方式來用,比如: f...
摘要:我們通過這個構(gòu)造函數(shù)為原型對象添加其他方法和屬性。這個屬性存在與實例與構(gòu)造函數(shù)的原型對象上直接,而不存在于實例與構(gòu)造函數(shù)之間。李小花班花張全蛋張全蛋李小花李小花我們在遍歷對象的的屬性的時候,經(jīng)常需要判斷屬性是否來自于對象的原型還是屬性。 引言 上面說了創(chuàng)建對象有字面量方式和工廠模式還有構(gòu)造函數(shù)模式,結(jié)果發(fā)現(xiàn)他們都各自有缺點,所以下面再給大家介紹幾種創(chuàng)建對象的方式,爭取能找到一種無痛的模...
閱讀 2826·2023-04-26 02:00
閱讀 2785·2019-08-30 15:54
閱讀 876·2019-08-30 11:15
閱讀 1512·2019-08-29 15:31
閱讀 926·2019-08-29 14:12
閱讀 498·2019-08-29 13:08
閱讀 849·2019-08-27 10:51
閱讀 2719·2019-08-26 12:17