摘要:動(dòng)態(tài)類型語(yǔ)言和鴨子類型編程語(yǔ)言按照數(shù)據(jù)類型大體可分為靜態(tài)類型語(yǔ)言和動(dòng)態(tài)類型語(yǔ)言。鴨子類型的概念至關(guān)重要,比如一個(gè)對(duì)象有了屬性,也可以依照下標(biāo)來(lái)存取屬性,這個(gè)對(duì)象就可以被當(dāng)做數(shù)組來(lái)使用。
前言
曾經(jīng)對(duì)Javascript的面向?qū)ο笙嚓P(guān)知識(shí)也有過(guò)了解,從各種博客、書籍上也學(xué)到了很多。但是最近在看《Javascript設(shè)計(jì)模式與開發(fā)實(shí)戰(zhàn)》這本書時(shí)發(fā)現(xiàn)該書對(duì)這方面的知識(shí)點(diǎn)介紹的很易于理解,因此總結(jié)出該文章分享給大家,同時(shí)也作為自己日后復(fù)習(xí)的筆記。
動(dòng)態(tài)類型語(yǔ)言和鴨子類型編程語(yǔ)言按照數(shù)據(jù)類型大體可分為靜態(tài)類型語(yǔ)言和動(dòng)態(tài)類型語(yǔ)言。
靜態(tài)類型語(yǔ)言就是指在編譯時(shí)就已經(jīng)確定了變量的類型,比如C++在聲明變量時(shí)的int關(guān)鍵字。
動(dòng)態(tài)類型語(yǔ)言的變量類型要在程序運(yùn)行時(shí)被賦值后才能確定。
在Javascript中,我們?cè)趯?duì)一個(gè)變量賦值時(shí),顯然不需要考慮它的類型。因此,Javascript是一門經(jīng)典的動(dòng)態(tài)類型語(yǔ)言。
動(dòng)態(tài)類型語(yǔ)言在實(shí)際編碼時(shí)帶來(lái)了很大的靈活性,我們可以嘗試調(diào)用任意對(duì)象的任意方法,而不需要考慮它原本是否被設(shè)計(jì)擁有該方法。
這些都建立在鴨子類型的概念上,通俗的說(shuō)法是“如果它走起路來(lái)像鴨子,叫起來(lái)也是鴨子,那么它就是鴨子。”
好吧我知道你可能不太理解,我們可以通過(guò)一個(gè)故事來(lái)深入理解:
從前在Javascript王國(guó)里,有一個(gè)國(guó)王,他覺(jué)得世界上最美妙的聲音就是鴨子的叫聲,于是國(guó)王召集大臣,要組建一個(gè)100只鴨子組成的合唱團(tuán)。但是大臣們找遍了全國(guó),只找到了999只鴨子,最后大臣發(fā)現(xiàn)有一只非常特別的雞,它的叫聲跟鴨子一模一樣,于是這只雞就成為了合唱團(tuán)的最后一員。
這個(gè)故事說(shuō)明,國(guó)王只是想要鴨子的叫聲,但它的主人是雞還是鴨都不重要。我們只關(guān)注對(duì)象的行為,而不關(guān)注對(duì)象本身。
通過(guò)代碼你可能能更好的的理解:
let duck = { duckSay: function () { console.log("ga") } } let chicken = { duckSay: function () { console.log("ga") } } // 合唱團(tuán) let choir = [] let joinChoir = function (animal) { if (animal && typeof animal.duckSay === "function") { choir.push(animal) console.log("加入合唱團(tuán)成功") } } joinChoir(duck) // 加入合唱團(tuán)成功 joinChoir(chicken) // 加入合唱團(tuán)成功
我們發(fā)現(xiàn),只要?jiǎng)游飺碛?b>duckSay方法,它就可以加入合唱團(tuán),而并不關(guān)心它到底是誰(shuí)。
鴨子類型的概念至關(guān)重要,比如一個(gè)對(duì)象有了length屬性,也可以依照下標(biāo)來(lái)存取屬性,這個(gè)對(duì)象就可以被當(dāng)做數(shù)組來(lái)使用。(這里可以思考我們?cè)谔幚砗瘮?shù)傳入的參數(shù)arguments時(shí)的一些操作)
多態(tài)是指同一操作作用于不同的對(duì)象上面,可以產(chǎn)生不同的解釋和不同的執(zhí)行結(jié)果。也就是給不同對(duì)象發(fā)送同一消息,會(huì)有不同的反饋。
這里我們依舊通過(guò)一個(gè)故事來(lái)講解:
主人家里養(yǎng)了兩只動(dòng)物,一只雞和一只鴨,當(dāng)主人發(fā)出叫的命令時(shí),鴨會(huì)gagaga的叫,而雞會(huì)gegege的叫。
上面的故事用代碼實(shí)現(xiàn)就是:
let makeSound = function (animal) { if (animal instanceof Duck) { console.log("ga") } else if (animal instanceof Chicken) { console.log("ge") } } let Duck = function () {} let Chicken = function () {} makeSound(new Duck()) // ga makeSound(new Chicken()) // ge
多態(tài)背后的思想是將“做什么”和“誰(shuí)去做以及怎樣去做”分離開,即將“不變的事情”和“可變的事情”分離開。這樣的程序是可生長(zhǎng)的,也是符合開放-封閉原則。
因此我們可以將不變的部分隔離出來(lái),也就是所有的動(dòng)物都會(huì)叫
let makeSound = function (animal) { animal.sound() }
然后把可變的部分封裝起來(lái):
let Duck = function () {} Duck.prototype.sound = function () { console.log("ga") } let Chicken = function () {} Chicken.prototype.sound = function () { console.log("ge") } makeSound(new Duck()) // ga makeSound(new Chicken()) // ge
再比如我們要開發(fā)一個(gè)地圖應(yīng)用,現(xiàn)在有百度和谷歌兩家地圖提供了API,且均提供了show()方法,代碼如下:
let googleMap = { show: function () { console.log("開始渲染谷歌地圖") } } let baiduMap = { show: function () { console.log("開始渲染百度地圖") } } let renderMap = function (type) { if (type === "google") { googleMap.show() } else if (type === "baidu") { baiduMap.show() } } renderMap("google") // 開始渲染谷歌地圖 renderMap("baidu") // 開始渲染百度地圖
可以看到,雖然renderMap()函數(shù)保持了一定的彈性,但是這種彈性很脆弱,如果再換另一個(gè)地圖,有需要修改renderMap函數(shù),繼續(xù)添加條件分支語(yǔ)句。
我們可以把程序相同的部分抽象出來(lái),即顯示某個(gè)地圖:
let renderMap = function (map) { if (map.show instanceof Function) { map.show() } }結(jié)束語(yǔ)
希望能為你帶來(lái)一些啟發(fā)。
參考資料:
《JavaScript 設(shè)計(jì)模式與開發(fā)實(shí)戰(zhàn)》 第一章
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/100426.html
摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:在中,并沒(méi)有對(duì)抽象類和接口的支持。例如,當(dāng)對(duì)象需要對(duì)象的能力時(shí),可以有選擇地把對(duì)象的構(gòu)造器的原型指向?qū)ο螅瑥亩_(dá)到繼承的效果。本節(jié)內(nèi)容為設(shè)計(jì)模式與開發(fā)實(shí)踐第一章筆記。 動(dòng)態(tài)類型語(yǔ)言 編程語(yǔ)言按數(shù)據(jù)類型大體可以分為兩類:靜態(tài)類型語(yǔ)言與動(dòng)態(tài)類型語(yǔ)言。 靜態(tài)類型語(yǔ)言在編譯時(shí)已確定變量類型,動(dòng)態(tài)類型語(yǔ)言的變量類型要到程序運(yùn)行時(shí),待變量被賦值后,才具有某種類型。 而JavaScript是一門典型...
摘要:什么是面向?qū)ο蟊疚牟辉谡撌觥=酉聛?lái)說(shuō)一下面向?qū)ο蟮娜筇卣髟诋?dāng)中的實(shí)現(xiàn)。封裝實(shí)現(xiàn)封裝實(shí)現(xiàn)就是是對(duì)象內(nèi)部的變化對(duì)外界是透明的不可見(jiàn)。這種做法使對(duì)象之間低耦合便于維護(hù)升級(jí)團(tuán)隊(duì)協(xié)作開發(fā)。。 概述 本來(lái)打算寫設(shè)計(jì)模式的,在談?wù)搄s的設(shè)計(jì)模式之前先說(shuō)一下js的面向?qū)ο?因?yàn)楹芏嘣O(shè)計(jì)模式的實(shí)現(xiàn)都摻雜著面向?qū)ο蟮乃枷?所以先做一下前期鋪墊。 js我們都知道是一種動(dòng)態(tài)類型腳本型語(yǔ)言,變量類型無(wú)法保證,...
閱讀 2595·2021-11-22 12:01
閱讀 1119·2021-11-15 11:37
閱讀 3703·2021-09-22 14:59
閱讀 1766·2021-09-04 16:45
閱讀 1397·2021-09-03 10:30
閱讀 1034·2021-08-11 11:18
閱讀 2473·2019-08-30 10:53
閱讀 2026·2019-08-29 15:13