/* ES5中除了引入一些新的對(duì)象與屬性外,他還提供了“嚴(yán)格模式”,所謂嚴(yán)格模式就是在ES5發(fā)布之前,世面上個(gè)版本互不兼容語(yǔ)言的子集。嚴(yán)格模式就是可選的,也就是說(shuō),選擇以嚴(yán)格模式執(zhí)行的代碼(以函數(shù)為單位,或者整個(gè)程序)都必須在其頭部作一下聲明: “user strick”; 或許在以后的版本中,嚴(yán)格模式有個(gè)能成為ES的默認(rèn)格式,甚至是唯一模式但現(xiàn)在它還是一個(gè)可選項(xiàng)。 */
在深入學(xué)習(xí)javascript之前,我們首相要了解一下“面向?qū)ο蟆钡木唧w含義,以及這種程序設(shè)計(jì)風(fēng)格的主要特征。下面我們列出一系列面向?qū)ο蟪绦蛟O(shè)計(jì)(OOP)中最常用到的概念:
對(duì)象、方法、屬性; 類; 封裝; 聚合; 重用與繼承; 多態(tài)。所謂對(duì)象,實(shí)際上就是指“事物”(包括人和物)在程序設(shè)計(jì)語(yǔ)言中的表現(xiàn)形式。這里的“事物”可以是任何東西(如某個(gè)客觀存在的對(duì)象,或者某些較為抽象的概念)。例如對(duì)于貓這種常見(jiàn)的對(duì)象來(lái)說(shuō),我們可以看到他們具有某些明確的特征(如顏色、名字、體型等),能執(zhí)行某些動(dòng)作(如喵喵叫、睡覺(jué)、躲起來(lái)、逃跑等)。在OOP語(yǔ)義中,這些對(duì)象特征都叫做屬性,而那些動(dòng)作則被稱為方法。
此外,我們還有個(gè)一口語(yǔ)方面的類比:
對(duì)象往往是用名詞來(lái)表示的方法一般都是些動(dòng)詞屬性值則往往是一些形容詞我們可以試一下。例如“一只黑色的貓?jiān)谖翌^上睡覺(jué)”這個(gè)句子中,“貓”就是一個(gè)對(duì)象,“黑色”則是一個(gè)顏色屬性值,而“睡覺(jué)”則是一個(gè)動(dòng)作,也就是OOP語(yǔ)義中的方法。甚至,為了進(jìn)一步證明這種類比的合理性,我們也將句子中的“在我頭上”看作動(dòng)作“睡覺(jué)”的一個(gè)限定條件,因此,它也可以被當(dāng)作被傳遞給“睡覺(jué)”方法的一個(gè)參數(shù)。
在現(xiàn)實(shí)生活中,相似對(duì)象之間往往都有一些共同的組成特征。列如蜂鳥和老鷹都具有鳥類的特征,因此他們可以被統(tǒng)稱為鳥類。在OOP中類實(shí)際上就是對(duì)象的設(shè)計(jì)藍(lán)圖或制作配方。“對(duì)象”這個(gè)詞我們有時(shí)候也叫做“實(shí)例”。所以我們可以說(shuō)老鷹是鳥類的一個(gè)實(shí)例。我們可以基于同一個(gè)類創(chuàng)建處許多不同的對(duì)象。因?yàn)轭惛嗟氖且环N模板,而對(duì)象則是在這些模板上被創(chuàng)建出來(lái)的實(shí)體。
但我們要明白,Javascript壓根就沒(méi)有類。該語(yǔ)言的一切都是基于對(duì)象,其依靠的是一套原型(PRotoetype)系統(tǒng)。而原型本身實(shí)際上也是一種對(duì)象,我們后面也會(huì)來(lái)詳細(xì)討論這個(gè)問(wèn)題。在傳統(tǒng)的面向?qū)ο蟮恼Z(yǔ)言中,我們一般會(huì)這樣描述自己的做法:“我基于person類創(chuàng)建個(gè)一個(gè)叫做Bob的新對(duì)象”。而在這種基于原型的面向?qū)ο笳Z(yǔ)言中,我們則要這樣描述:“我將現(xiàn)有的person對(duì)象擴(kuò)展成了一個(gè)叫做Bob的新對(duì)象”。
封裝是另一個(gè)與OOP相關(guān)的概念,其主要用于闡述對(duì)象中所包含的內(nèi)容。封裝的概念通常由兩部分組成。
相關(guān)的數(shù)據(jù)(用于存儲(chǔ)屬性)基于這些數(shù)據(jù)所能做的事(所能調(diào)用的方法)除此之外,這個(gè)術(shù)語(yǔ)中還有另一層信息隱藏的概念,這完全是另一方面的問(wèn)題。因此我們?cè)诶斫膺@個(gè)概念時(shí),必須要留意它在OOP中的具體語(yǔ)境。
以一個(gè)MP3播放器為例。如果我們假設(shè)它是一個(gè)對(duì)象,那么作為該對(duì)象的用戶,我們需要一些類似與像按鈕、顯示屏這樣的接口。這些接口會(huì)幫助我們使用該對(duì)象(如播放歌曲等)。至于他們內(nèi)部是如何工作的,我們并不清楚,而且大多數(shù)情況下也不會(huì)在乎這些。換句話說(shuō),這些接口的實(shí)現(xiàn)對(duì)我來(lái)說(shuō)的隱藏的。同樣的,在OOP中也是如此。當(dāng)我們?cè)诖a中調(diào)用一個(gè)對(duì)象的方法時(shí),無(wú)論該對(duì)象是來(lái)自我們自己實(shí)現(xiàn)還是某個(gè)第三方庫(kù),我們都不需要知道該方法是如何工作的。在編譯型語(yǔ)言中,我們甚至都無(wú)法查看這些對(duì)象的工作代碼。
所謂聚合,有時(shí)候也叫做組合。實(shí)際上是指我們將幾個(gè)現(xiàn)有對(duì)象合并成一個(gè)新對(duì)象的過(guò)程??傊@個(gè)概念所強(qiáng)調(diào)的就是這種將多個(gè)對(duì)象合而為一的能力。通過(guò)聚合這種強(qiáng)有力的方法,我們可以將一個(gè)問(wèn)題分解成多個(gè)更小的問(wèn)題。這樣一來(lái),問(wèn)題就會(huì)顯的更易于管理(便于我們各個(gè)擊破)。當(dāng)一個(gè)問(wèn)題域的復(fù)雜過(guò)程令我們難以接受時(shí),我就就可以考慮將它分成若干個(gè)子問(wèn)題區(qū),并且必要的話,這些問(wèn)題區(qū)還可以繼續(xù)分解成更小的分區(qū)。這樣做有利于我們從幾個(gè)不同的抽象層來(lái)樂(lè)了從這個(gè)問(wèn)題。
例如,個(gè)人電腦是一個(gè)非常復(fù)雜的對(duì)象,我們不可能知道它啟動(dòng)時(shí)所發(fā)生的全部事情。但如果我們將這個(gè)問(wèn)題的抽象級(jí)別降低到一定的程度,只關(guān)注它幾個(gè)組件對(duì)象的初始化工作,例如顯示器對(duì)象、鼠標(biāo)對(duì)象、鍵盤對(duì)象等,我們就很容易深入了解這些子對(duì)象情況,然后再將這些部分的結(jié)構(gòu)合并起來(lái),之前的那個(gè)復(fù)雜的問(wèn)題就迎刃而解了。
通過(guò)繼承這種方式,我們可以非常優(yōu)雅的實(shí)現(xiàn)對(duì)現(xiàn)有代碼的重用。例如我們有一個(gè)叫做Person的一般性對(duì)象,其中包含一些姓名、出生日期之類的屬性,以及一些功能性的函數(shù),如步行、談話、睡覺(jué)、吃飯等。然后當(dāng)我們發(fā)現(xiàn)自己需要一個(gè)Programmer對(duì)象時(shí),當(dāng)然,這時(shí)候你可以再將Person對(duì)象中所有的方法與屬性重新實(shí)現(xiàn)一遍,但除此之外還有一種更聰明的做法,即我們可以讓Programmer繼承自Person,這樣就省去了我們不少工作。因?yàn)镻rogrammer對(duì)象只需要實(shí)現(xiàn)屬于它自己的那部分特殊功能(例如“編寫代碼”),而其余部分只需要重用Person的實(shí)現(xiàn)即可。
在傳統(tǒng)的OOP環(huán)境中,繼承通常指的時(shí)類與類之間的關(guān)系,但由于JS中不存在類,因此它的繼承只發(fā)生在對(duì)象之間。
當(dāng)一個(gè)對(duì)象繼承自另一個(gè)對(duì)象時(shí),通常會(huì)往其中加入新的方法,以擴(kuò)展被繼承的老對(duì)象。我們通常將這一過(guò)程稱之為“B繼承自A”或“B擴(kuò)展自A”。另外對(duì)于新對(duì)象來(lái)說(shuō),它可以根據(jù)自己的需要從繼承的那組方法中選擇幾個(gè)來(lái)重新定義。這樣做并不會(huì)改變對(duì)象的接口,因?yàn)槠浞椒窍嗤?,只不過(guò)當(dāng)我們調(diào)用新對(duì)象時(shí),該方法的行為與之前的不同了。我們將這種重定義繼承方法的過(guò)程叫做覆寫。
在之前的例子中,我們的Programmer對(duì)象繼承了上一級(jí)對(duì)象Person的所有方法。這意為著這兩個(gè)對(duì)象都實(shí)現(xiàn)了“talk”等方法。現(xiàn)在,我們的代碼中有一個(gè)叫做Bob的變量,即便我們不知道它是一個(gè)Person對(duì)象還是一個(gè)Programmer對(duì)象情況下,也依然可以直接調(diào)用該對(duì)象的“talk”方法,而不必?fù)?dān)心這會(huì)影響代碼的正常工作。類似這種不同對(duì)象通過(guò)相同的方法調(diào)用來(lái)實(shí)現(xiàn)各自行為的能力,我們就稱之為多態(tài)。
特征描述 | 相應(yīng)概念 |
---|---|
Bob是一個(gè)男人 | 對(duì)象 |
Bob出生于1990年,男性黑頭發(fā) | 屬性 |
Bob能吃飯、睡覺(jué)、喝水、做夢(mèng),以及記錄自己的年齡 | 方法 |
Bob是Programmer類的一個(gè)實(shí)例 | 傳統(tǒng)OOP中的類 |
Bob是一個(gè)由Programmer對(duì)象擴(kuò)展而來(lái)的新對(duì)象 | 基于原型OOP中的原型對(duì)象 |
Bob對(duì)象包含了數(shù)據(jù)(出生日期等)和基于這些數(shù)據(jù)的方法(例如記錄年齡) | 封裝 |
我們并不需要知道其記錄年齡的方法是如何實(shí)現(xiàn)的。對(duì)象通常都可以擁有一個(gè)私有數(shù)據(jù),例如對(duì)閏年二月的天數(shù),我們就不知道,而且也不會(huì)想知道 | 信息隱藏 |
Bob只是整個(gè)WEB開(kāi)發(fā)團(tuán)隊(duì)對(duì)象的一部分,此外開(kāi)發(fā)團(tuán)隊(duì)還包含了一個(gè)Designer對(duì)象Jill,以及一個(gè)ProjectManager對(duì)象Jack | 聚合、組合 |
Designer、ProjectManager、Programmer都是分別擴(kuò)展自Person對(duì)象的新對(duì)象 | 繼承 |
我們可以隨時(shí)調(diào)用Bob、Jill和Jack這三個(gè)對(duì)象各自的talk方法,他們都可以正常工作,盡管這些方法會(huì)產(chǎn)生不同的結(jié)果(如Bob可能談的更多的是代碼性能,Jill更傾向于談代碼的優(yōu)雅性,而Jack強(qiáng)調(diào)的是最后期限)??傊總€(gè)對(duì)象都可以重新自定義他們的繼承方法talk | 多態(tài)、方法覆寫 |
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注