摘要:構(gòu)造函數(shù)通過原型繼承了構(gòu)造函數(shù)和原型,這就形成了一個(gè)鏈條,通俗的講就是原型鏈繼承。而且方法只能冒充構(gòu)造函數(shù)里面的屬性和方法而無法冒充原型對象里面的屬性和方法還有最大的問題就是重復(fù)使用。
前言: 寫到這里,差不多就把OOP完結(jié)了,寫了幾篇OOP的文章,但是只是略懂皮毛,可能深入的OOP還有很多,但是我感覺寫到這里也算是差不多完結(jié)了。
繼承
繼承是面向?qū)ο蟊容^核心的概念,其他語言可能實(shí)現(xiàn)繼承有兩種方式:接口,繼承。而ECMAscript只有繼承。
原型鏈繼承
通俗的講,就是通過構(gòu)造函數(shù)的原型對象去繼承父類。上一篇文章我們說過。繼承最大的優(yōu)點(diǎn)也是缺點(diǎn)就是共享,看代碼:
function First() { //創(chuàng)建一個(gè)構(gòu)造函數(shù)(作為父類) this.a = "abc"; //添加屬性 } function Second() { //另一個(gè)構(gòu)造函數(shù)(作為派生類也稱為子類) this.b = "10"; //同上 } Second.prototype = new First(); //子類的原型對象添加父類的實(shí)例。 var box = new Second(); //實(shí)例化并賦值給一個(gè)變量 alert(box.a); //返回abc
大家看的出,第二個(gè)構(gòu)造函數(shù)內(nèi)并沒有a這個(gè)屬性,但是我們從原型去添加一個(gè)父類的實(shí)例化,就能繼承父類的構(gòu)造體內(nèi)的和原型對象。
Second構(gòu)造函數(shù)通過原型繼承了First構(gòu)造函數(shù)和原型,這就形成了一個(gè)鏈條,通俗的講就是:原型鏈繼承。
也可以這么說,用對象實(shí)例化賦值給子類的原型屬性,會(huì)將父類的構(gòu)造函數(shù)里面的信息和原型里面的信息都交給子類。
重談原型:還是那句話,字面量重寫原型會(huì)中斷關(guān)系,使用引用類型的原型,并且子類型還無法給超類型傳遞參數(shù)。
對象冒充
不知道大家發(fā)現(xiàn)沒有,父類是無法傳參的,而且引用共享的問題,我們可以使用對象冒充的方法去實(shí)現(xiàn)繼承。
function First (b) { //創(chuàng)建一個(gè)構(gòu)造函數(shù)并傳參 this.a = ["a","b","c"]; //添加一個(gè)屬性為一個(gè)數(shù)組 this.b = b; //添加屬性得到傳進(jìn)去的值 } function Second (b) { //同上 First.call(this,b); //對象冒充 } var second = new Second(100); //實(shí)例化子類并賦值給變量 alert(second.a); //返回a,b,c alert(second.b); //返回100
從上面的代碼我們可以看出,我們解決了父類傳參問題,也解決了引用共享問題。但是沒有原型。而且call方法只能冒充構(gòu)造函數(shù)里面的屬性和方法而無法冒充原型對象里面的屬性和方法
還有最大的問題就是重復(fù)使用。
我們來用代碼證明上面的話,就是call冒充只是冒充構(gòu)造函數(shù)里面的方法和屬性。
/*alert(second.a); 返回a,b,c */ second.a.push("d"); //給數(shù)組末尾添加一個(gè)d alert(second.a); //返回a,b,c,d
從上面代碼看出,并沒有繼承原型,也就是共享。重復(fù)使用更是不可能的。
原型鏈+冒充
當(dāng)然我們可以變通一下,將上面兩種方法結(jié)合一下不就達(dá)到效果了么!我們大概的思想是該私有化的屬性和方法就私有化,該共享的公有化的方法就放在原型里面不就得了!
function First (b) { this.a = ["a","b","c"]; this.b = b; } First.prototype.c = function () { //公有化方法放在原型中 return this.a + this.b; }; function Second (b) { First.call(this,b); //對象冒充 } Second.prototype = new First(); //子類的原型對象添加父類的實(shí)例 var second = new Second(100); //實(shí)例化并賦值給變量 alert(second.c()); 返回a,b,c10
從上面的例子用可以看出,我們將我們不想共享的屬性和方法放在構(gòu)造函數(shù)中,而我們想私有化的方法放在原型對象中,達(dá)到了清晰代碼的作用,而且解決了重復(fù)使用和傳參的問題并且有了原型!
總結(jié):
說了這么多,其實(shí)Javascript中實(shí)現(xiàn)繼承是十分靈活的,并沒有一種最好的方法,需要根據(jù)不同的需求實(shí)現(xiàn)不同方式的繼承,最重要的是要理解Javascript中實(shí)現(xiàn)繼承的原理,也就是原型和原型鏈的問題,只要理解了這些,自己也就可以很輕松實(shí)現(xiàn)繼承了。
Brian.Lee
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91320.html
摘要:構(gòu)造函數(shù)上一章我們講了工廠模式,它的缺點(diǎn)就是無法識(shí)別到底哪個(gè)屬于哪個(gè)的問題。我們可以用構(gòu)造函數(shù)來解決這個(gè)識(shí)別問題。來比較構(gòu)造函數(shù)內(nèi)的值就可以看出到底是什么類型。 構(gòu)造函數(shù) 上一章我們講了工廠模式,它的缺點(diǎn)就是無法識(shí)別到底哪個(gè)屬于哪個(gè)的問題。我們可以用構(gòu)造函數(shù)來解決這個(gè)識(shí)別問題。 //構(gòu)造函數(shù) function Create(a,b) { this.a =a; this...
摘要:工廠模式優(yōu)點(diǎn)集中實(shí)例化,可以傳參等缺點(diǎn)分不清屬于哪個(gè)對象我們先來談?wù)剝?yōu)點(diǎn),看例子集中實(shí)例化返回實(shí)例化對象返回返回不難看出,工廠模式比上面的例子減少了很多代碼。 ECMAscript開發(fā)的兩種模式:1.過程化 2.OOP(面向?qū)ο? 面向?qū)ο蟮恼Z言有一個(gè)標(biāo)志,那就是類的概念,而通過類可以創(chuàng)建任意多個(gè)具有相同屬性的方法的對象。但是ECMAscript中沒有類的概念! 又談作用域 首先...
摘要:上一章我們談了構(gòu)造函數(shù),他的唯一特點(diǎn)就是比較了地址不相同,因?yàn)榇蠹抑酪妙愋褪潜容^的引用。也就是說不用在構(gòu)造函數(shù)中定義對象實(shí)例,而是直接將這些添加到原型當(dāng)中。如果構(gòu)造函數(shù)實(shí)例里面沒有,就去原型里面查找,如果有就立即返回。 上一章我們談了構(gòu)造函數(shù),他的唯一特點(diǎn)就是比較了地址不相同,因?yàn)榇蠹抑酪妙愋褪潜容^的引用。我們來談?wù)勗汀?原型 我們每創(chuàng)建一個(gè)函數(shù)都有一個(gè)原型(prototyp...
摘要:面向?qū)ο竺嫦驅(qū)ο缶幊痰娜Q是,簡稱,面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建基于現(xiàn)實(shí)世界模型的一種編程模式。面向?qū)ο缶幊痰娜齻€(gè)主要特征是封裝繼承多態(tài)。 面向?qū)ο?面向?qū)ο缶幊痰娜Q是Object Oriented Programming,簡稱OOP,面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建基于現(xiàn)實(shí)世界模型的一種編程模式。面向?qū)ο缶幊炭梢钥醋鍪鞘褂靡幌盗袑ο笙嗷f(xié)作的軟件設(shè)計(jì),面向?qū)ο蟪绦蛟O(shè)計(jì)的目的是在編程中促...
摘要:而哈士奇區(qū)別于普通狗,又有新的特征逗比,愛搗亂為了保證類之間的松綁定,通常會(huì)繼承抽象類,而且是淺繼承只有一層子類。如果知道所有類都會(huì)共享一個(gè)公共的行為實(shí)現(xiàn),就使用抽象類,并在其中實(shí)現(xiàn)該行為。 為什么使用OOP OOP是一個(gè)模塊化的過程,目的是為了把復(fù)雜問題簡單化,一個(gè)模塊解決一個(gè)復(fù)雜問題的某一個(gè)方面,即一個(gè)類應(yīng)當(dāng)只有一個(gè)職責(zé) OOP區(qū)別于順序式編程與過程式編程,在于: 1.順序編程...
閱讀 6949·2021-09-22 15:36
閱讀 5718·2021-09-02 10:20
閱讀 1883·2019-08-30 15:44
閱讀 2662·2019-08-29 14:06
閱讀 1163·2019-08-29 11:17
閱讀 1612·2019-08-26 14:05
閱讀 3108·2019-08-26 13:50
閱讀 1562·2019-08-26 10:26