摘要:當(dāng)我們對一些函數(shù)發(fā)出調(diào)用的消息時,這些函數(shù)會返回不同的執(zhí)行結(jié)果,這是多態(tài)性的一種體現(xiàn),也是很多設(shè)計(jì)模式在中可以用高階函數(shù)來代替實(shí)現(xiàn)的原因。
PS:上一篇文章發(fā)表之后,很多朋友關(guān)注了本人的思否和掘金的博客,雖然關(guān)注的朋友還有有限,但足夠讓我把自己在技術(shù)上的問題積累分享給大家,也希望大家能夠喜歡,同時能動一動手指,給一顆心(贊),博主會持續(xù)更新下去 多態(tài)
本文是《javascript設(shè)計(jì)模式與開發(fā)實(shí)踐》一書學(xué)習(xí)筆記,因書中所表述的概念簡單明了,故將整本書的筆記奉上,全部文章大概在20篇左右,還請朋友們持續(xù)關(guān)注
動態(tài)語言類型編程語言按照數(shù)據(jù)類型大體可以分為兩類,一類是靜態(tài)類型語言,另一類是動態(tài)類型語言
靜態(tài)類型語言,聲明任何變量或者形參都需要指定類型,例如java語言。
動態(tài)類型語言,聲明任何變量或者形參都不需要指定類型,javascript就是動態(tài)類型語言。
所謂動態(tài),可以多層面的理解,首先,聲明變量不需要指定類型,其次,在多態(tài)思想下,java中需要利用父類實(shí)現(xiàn)多態(tài),而javascript就不需要,本身自帶多態(tài)屬性。
多態(tài)熟悉java的朋友知道,java三大特征之一就有多態(tài),多態(tài)給java帶來了很大的靈活性,很多設(shè)計(jì)模式也是通過多態(tài)來實(shí)現(xiàn),java中的多態(tài)涉及到向上轉(zhuǎn)型和向下轉(zhuǎn)型,而javascript(以下簡稱js)的"多態(tài)"就相對來說容易實(shí)現(xiàn)
我們來看一段“多態(tài)”的js代碼
var makeSound = function(an) { if(an instanceof Duck) { console.log("嘎嘎嘎"); } else if(an instanceof Dog) { console.log("汪汪汪"); } } var Dog = function(){}; var Duck = function(){}; makeSound(new Dog()); makeSound(new Duck());
這段代碼確實(shí)體現(xiàn)了“多態(tài)性”,當(dāng)我們分別向鴨和雞發(fā)出“叫喚”的消息時,它們根據(jù)此 消息作出了各自不同的反應(yīng),但是這樣寫會有一個弊端,當(dāng)更多的類型出現(xiàn)時,我們要不斷的修改makeSound函數(shù),后期makeSound函數(shù)也會變得十分巨大,這不符合良好代碼設(shè)計(jì)的規(guī)范,多態(tài)背后的思想是將“做什么”和“誰去做以及怎樣去做”分離開來,也就是將“不變的事 物”與 “可能改變的事物”分離開來。在這個故事中,動物都會叫,這是不變的,但是不同類 型的動物具體怎么叫是可變的。把不變的部分隔離出來,把可變的部分封裝起來,這給予了我們 擴(kuò)展程序的能力,程序看起來是可生長的,也是符合開放—封閉原則的,相對于修改代碼來說, 僅僅增加代碼就能完成同樣的功能,這顯然優(yōu)雅和安全得多
首先,我們把makeSound函數(shù)修改一下:
var makeSound = function(an) { an.speak(); }
這段代碼傳入一個對象,然后調(diào)用對象的speak函數(shù)
var Duck = function(){} Duck.prototype.sound = function(){ console.log( "嘎嘎嘎" ); }; var Chicken = function(){} Chicken.prototype.sound = function(){ console.log( "咯咯咯" ); }; makeSound( new Duck() ); // 嘎嘎嘎 makeSound( new Chicken() );
現(xiàn)在我們向鴨和雞都發(fā)出“叫喚”的消息,它們接到消息后分別作出了不同的反應(yīng)。如果有 一天動物世界里又增加了一只狗,這時候只要簡單地追加一些代碼就可以了,而不用改動以前的 makeSound 函數(shù)
類型檢查和多態(tài)現(xiàn)在,我們來進(jìn)一步了解多態(tài),之前說到,java的多態(tài)需要利用繼承來實(shí)現(xiàn),我們現(xiàn)在把動物的例子換成java代碼
public class Duck { public void speak(){ System.out.println( "嘎嘎嘎" ); } } public class Dog { public void speak(){ System.out.println( "汪汪汪" ); } } public class AnimalSpeak{ public void makeSound(Duck duck){ duck.speak(); } } public static void main(String args[]){ AnimalSpeak an = new AnimalSpeak(); Duck duck = new Duck(); an.makeSound(duck); // 輸出:嘎嘎嘎 }
現(xiàn)在鴨子已經(jīng)順利叫出來了,但是我們想讓狗也叫,發(fā)現(xiàn)不太容易實(shí)現(xiàn),因?yàn)閙akeSound函數(shù)中,形參是Duck類型,傳入Dog類型一定會報(bào)錯,這個時候繼承就出現(xiàn)了,java設(shè)計(jì)思路是我先創(chuàng)建一個父類,具體傳入的類型由子類決定,但是makeSound函數(shù)中的形參確是父類類型,實(shí)現(xiàn)如下:
public abstract class Animal{ abstract void speak(); // 抽象方法 } public class Duck extends Animal { public void speak(){ // 覆寫父類中的抽象方法 System.out.println( "嘎嘎嘎" ); } } public class Dog extends Animal { public void speak(){ // 覆寫父類中的抽象方法 System.out.println( "汪汪汪" ); } } public class AnimalSpeak{ public void makeSound(Animal an){ an.speak(); } } public static void main(String args[]){ AnimalSpeak an = new AnimalSpeak(); Animal duck = new Duck(); Animal dog = new Dog(); an.makeSound(duck); // 輸出:嘎嘎嘎 an.makeSound(dog); // 輸出:汪汪汪 }js中的多態(tài)
JavaScript 對象的多態(tài)性是與生俱來的,為什么這么說? 仔細(xì)看看這兩個函數(shù):
public void makeSound(Animal an){ an.speak(); } function(an) { an.speak(); }
js和java中的函數(shù)的形參是不同的,java定死了傳入的類型,而js是動態(tài)的,js隨便可以傳入任何類型,所以,我們之前說js是動態(tài)類型語言,在 JavaScript 這種將函數(shù)作為一等對象的語言中,函數(shù)本身也是對象,函數(shù)用來封裝行為并 且能夠被四處傳遞。當(dāng)我們對一些函數(shù)發(fā)出“調(diào)用”的消息時,這些函數(shù)會返回不同的執(zhí)行結(jié) 果,這是“多態(tài)性”的一種體現(xiàn),也是很多設(shè)計(jì)模式在 JavaScript 中可以用高階函數(shù)來代替實(shí)現(xiàn)的原因。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/93132.html
摘要:在中,并沒有對抽象類和接口的支持。例如,當(dāng)對象需要對象的能力時,可以有選擇地把對象的構(gòu)造器的原型指向?qū)ο螅瑥亩_(dá)到繼承的效果。本節(jié)內(nèi)容為設(shè)計(jì)模式與開發(fā)實(shí)踐第一章筆記。 動態(tài)類型語言 編程語言按數(shù)據(jù)類型大體可以分為兩類:靜態(tài)類型語言與動態(tài)類型語言。 靜態(tài)類型語言在編譯時已確定變量類型,動態(tài)類型語言的變量類型要到程序運(yùn)行時,待變量被賦值后,才具有某種類型。 而JavaScript是一門典型...
摘要:為什么要學(xué)習(xí)設(shè)計(jì)模式做事情之前問個為什么總是好的。設(shè)計(jì)模式的使用方法關(guān)于使用方式,像我這種初學(xué)者最容易犯的錯誤就是生搬硬套,但是模仿本來也是學(xué)習(xí)的一個過程,最重要的事情是在模仿中要學(xué)會思考。 為什么要學(xué)習(xí)設(shè)計(jì)模式? 做事情之前問個為什么總是好的。關(guān)于設(shè)計(jì)模式的好壞,我在知乎上也看過一些討論,有知友對其提出過一些疑問,里面有一些關(guān)于設(shè)計(jì)模式的觀點(diǎn): 設(shè)計(jì)模式有何不妥,所謂的荼毒體現(xiàn)在哪...
摘要:之前,本質(zhì)上不能算是一門面向?qū)ο蟮木幊陶Z言,因?yàn)樗鼘τ诜庋b繼承多態(tài)這些面向?qū)ο笳Z言的特點(diǎn)并沒有在語言層面上提供原生的支持。所以在中出現(xiàn)了等關(guān)鍵字,解決了面向?qū)ο笾谐霈F(xiàn)了問題。 ES6之前,javascript本質(zhì)上不能算是一門面向?qū)ο蟮木幊陶Z言,因?yàn)樗鼘τ诜庋b、繼承、多態(tài)這些面向?qū)ο笳Z言的特點(diǎn)并沒有在語言層面上提供原生的支持。但是,它引入了原型(prototype)的概念,可以讓我們以...
摘要:下面是我仿照適配器模式改進(jìn)的谷歌地圖百度地圖適配器參數(shù)配置適配器地圖只關(guān)注發(fā)出顯示地圖而不關(guān)注具體用哪種地圖當(dāng)增加了搜搜地圖,我們需要添加搜搜地圖的方法以及修改適配器地圖參數(shù)而不需要對函數(shù)進(jìn)行修改搜搜地圖 不多說先上一段代碼(轉(zhuǎn)載自《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》) //谷歌地圖show方法 var googleMap = { ...
摘要:閱讀小札一閱讀前自大學(xué)課上,就開始接觸設(shè)計(jì)模式,但對設(shè)計(jì)模式卻鮮有研究與實(shí)踐。第二部分是核心部分,由淺到深講解個設(shè)計(jì)模式。設(shè)計(jì)模式遵循的原則所有設(shè)計(jì)模式罪訓(xùn)的一條原則就是找出程序中變化的地方,并將變化封裝起來。 閱讀小札 · 閱讀前 自大學(xué)Java課上,就開始接觸設(shè)計(jì)模式,但對設(shè)計(jì)模式卻鮮有研究與實(shí)踐。最近向公司反映和游說技術(shù)提升,得以獲得公司提供購書機(jī)會,借此認(rèn)真學(xué)習(xí)前端學(xué)習(xí)之路的...
閱讀 2404·2021-10-14 09:43
閱讀 2435·2021-09-09 09:34
閱讀 1601·2019-08-30 12:57
閱讀 1198·2019-08-29 14:16
閱讀 716·2019-08-26 12:13
閱讀 3201·2019-08-26 11:45
閱讀 2282·2019-08-23 16:18
閱讀 2652·2019-08-23 15:27