摘要:構造函數通過原型繼承了構造函數和原型,這就形成了一個鏈條,通俗的講就是原型鏈繼承。而且方法只能冒充構造函數里面的屬性和方法而無法冒充原型對象里面的屬性和方法還有最大的問題就是重復使用。
前言: 寫到這里,差不多就把OOP完結了,寫了幾篇OOP的文章,但是只是略懂皮毛,可能深入的OOP還有很多,但是我感覺寫到這里也算是差不多完結了。
繼承
繼承是面向對象比較核心的概念,其他語言可能實現繼承有兩種方式:接口,繼承。而ECMAscript只有繼承。
原型鏈繼承
通俗的講,就是通過構造函數的原型對象去繼承父類。上一篇文章我們說過。繼承最大的優點也是缺點就是共享,看代碼:
function First() { //創建一個構造函數(作為父類) this.a = "abc"; //添加屬性 } function Second() { //另一個構造函數(作為派生類也稱為子類) this.b = "10"; //同上 } Second.prototype = new First(); //子類的原型對象添加父類的實例。 var box = new Second(); //實例化并賦值給一個變量 alert(box.a); //返回abc
大家看的出,第二個構造函數內并沒有a這個屬性,但是我們從原型去添加一個父類的實例化,就能繼承父類的構造體內的和原型對象。
Second構造函數通過原型繼承了First構造函數和原型,這就形成了一個鏈條,通俗的講就是:原型鏈繼承。
也可以這么說,用對象實例化賦值給子類的原型屬性,會將父類的構造函數里面的信息和原型里面的信息都交給子類。
重談原型:還是那句話,字面量重寫原型會中斷關系,使用引用類型的原型,并且子類型還無法給超類型傳遞參數。
對象冒充
不知道大家發現沒有,父類是無法傳參的,而且引用共享的問題,我們可以使用對象冒充的方法去實現繼承。
function First (b) { //創建一個構造函數并傳參 this.a = ["a","b","c"]; //添加一個屬性為一個數組 this.b = b; //添加屬性得到傳進去的值 } function Second (b) { //同上 First.call(this,b); //對象冒充 } var second = new Second(100); //實例化子類并賦值給變量 alert(second.a); //返回a,b,c alert(second.b); //返回100
從上面的代碼我們可以看出,我們解決了父類傳參問題,也解決了引用共享問題。但是沒有原型。而且call方法只能冒充構造函數里面的屬性和方法而無法冒充原型對象里面的屬性和方法
還有最大的問題就是重復使用。
我們來用代碼證明上面的話,就是call冒充只是冒充構造函數里面的方法和屬性。
/*alert(second.a); 返回a,b,c */ second.a.push("d"); //給數組末尾添加一個d alert(second.a); //返回a,b,c,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(); //子類的原型對象添加父類的實例 var second = new Second(100); //實例化并賦值給變量 alert(second.c()); 返回a,b,c10
從上面的例子用可以看出,我們將我們不想共享的屬性和方法放在構造函數中,而我們想私有化的方法放在原型對象中,達到了清晰代碼的作用,而且解決了重復使用和傳參的問題并且有了原型!
總結:
說了這么多,其實Javascript中實現繼承是十分靈活的,并沒有一種最好的方法,需要根據不同的需求實現不同方式的繼承,最重要的是要理解Javascript中實現繼承的原理,也就是原型和原型鏈的問題,只要理解了這些,自己也就可以很輕松實現繼承了。
Brian.Lee
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91320.html
摘要:構造函數上一章我們講了工廠模式,它的缺點就是無法識別到底哪個屬于哪個的問題。我們可以用構造函數來解決這個識別問題。來比較構造函數內的值就可以看出到底是什么類型。 構造函數 上一章我們講了工廠模式,它的缺點就是無法識別到底哪個屬于哪個的問題。我們可以用構造函數來解決這個識別問題。 //構造函數 function Create(a,b) { this.a =a; this...
摘要:工廠模式優點集中實例化,可以傳參等缺點分不清屬于哪個對象我們先來談談優點,看例子集中實例化返回實例化對象返回返回不難看出,工廠模式比上面的例子減少了很多代碼。 ECMAscript開發的兩種模式:1.過程化 2.OOP(面向對象) 面向對象的語言有一個標志,那就是類的概念,而通過類可以創建任意多個具有相同屬性的方法的對象。但是ECMAscript中沒有類的概念! 又談作用域 首先...
摘要:上一章我們談了構造函數,他的唯一特點就是比較了地址不相同,因為大家知道引用類型是比較的引用。也就是說不用在構造函數中定義對象實例,而是直接將這些添加到原型當中。如果構造函數實例里面沒有,就去原型里面查找,如果有就立即返回。 上一章我們談了構造函數,他的唯一特點就是比較了地址不相同,因為大家知道引用類型是比較的引用。我們來談談原型。 原型 我們每創建一個函數都有一個原型(prototyp...
摘要:面向對象面向對象編程的全稱是,簡稱,面向對象編程是用抽象方式創建基于現實世界模型的一種編程模式。面向對象編程的三個主要特征是封裝繼承多態。 面向對象 面向對象編程的全稱是Object Oriented Programming,簡稱OOP,面向對象編程是用抽象方式創建基于現實世界模型的一種編程模式。面向對象編程可以看做是使用一系列對象相互協作的軟件設計,面向對象程序設計的目的是在編程中促...
摘要:而哈士奇區別于普通狗,又有新的特征逗比,愛搗亂為了保證類之間的松綁定,通常會繼承抽象類,而且是淺繼承只有一層子類。如果知道所有類都會共享一個公共的行為實現,就使用抽象類,并在其中實現該行為。 為什么使用OOP OOP是一個模塊化的過程,目的是為了把復雜問題簡單化,一個模塊解決一個復雜問題的某一個方面,即一個類應當只有一個職責 OOP區別于順序式編程與過程式編程,在于: 1.順序編程...
閱讀 6899·2021-09-22 15:36
閱讀 5699·2021-09-02 10:20
閱讀 1875·2019-08-30 15:44
閱讀 2657·2019-08-29 14:06
閱讀 1160·2019-08-29 11:17
閱讀 1604·2019-08-26 14:05
閱讀 3100·2019-08-26 13:50
閱讀 1558·2019-08-26 10:26