JavaScript王國裡的鴨子合唱團

來源:互聯網
上載者:User

標籤:靜態類型語言   javascript   設計模式   物件導向   

程式設計語言按照資料類型大體可以分為兩類,一類是靜態類型語言,另一類是動態類型語言。

靜態類型語言在編譯時間便已確定變數的類型,而動態類型語言的變數類型要到程式啟動並執行時候,待變數被賦予某個值之後,才會具有某種類型。

靜態類型語言的優點首先是在編譯時間就能發現類型不符的錯誤,編輯器可以協助我們提前避免程式在運行期間有可能發生的一些錯誤。其次,如果在程式中明確地規定了資料類型,編譯器還可以針對這些資訊對程式進行一些最佳化工作,提高程式執行速度。

靜態類型語言的缺點首先是迫使程式員依照強契約來編寫程式,為每個變數規定資料類型,歸根結底只是輔助我們編寫可靠性高程式的一種手段,而不是編寫程式的目的,畢竟大部分人編寫程式的目的是為了完成需求交付生產。其次,類型的聲明也會增加更多的代碼,在程式編寫過程中,這些細節會讓程式員的精力從思考商務邏輯上分散開來。

動態類型語言的優點是編寫的代碼數量更少,看起來也更加簡潔,程式員可以把精力更多地放在商務邏輯上面。雖然不區分類型在某些情況下會讓程式變得難以理解,但整體而言,代碼量越少,越專註於邏輯表達,對閱讀程式是越有協助的。

動態類型語言的缺點是無法保證變數的類型,從而在程式的運行期有可能發生跟類型相關的錯誤。這好像在商店買了一包牛肉辣條,但是要真正吃到嘴裡才知道是不是牛肉味。

在JavaScript中,當我們對一個變數賦值時,顯然不需要考慮它的類型,因此,JavaScript是一門典型的動態類型語言。

動態類型語言對變數類型的寬容給實際編碼帶來了很大的靈活性。由於無需進行類型檢測,我們可以嘗試調用任何對象的任意方法,而無需去考慮它原本是否被設計為擁有該方法。

這一切都建立在鴨子類型(duck typing)的概念上,鴨子類型的通俗說法是:“如果它走起路來像鴨子,叫起來也是鴨子,那麼它就是鴨子。”

我們可以通過一個小故事來更深刻地瞭解鴨子類型。

從前在JavaScript王國裡,有一個國王,他覺得世界上最美妙的聲音就是鴨子的叫聲,於是國王召集大臣,要組建一個1000隻鴨子組成的合唱團。大臣們找遍了全國,終於找到999隻鴨子,但是始終還差一隻,最後大臣發現有一隻非常特別的雞,它的叫聲跟鴨子一模一樣,於是這隻雞就成為了合唱團的最後一員。

這個故事告訴我們,國王要聽的只是鴨子的叫聲,這個聲音的主人到底是雞還是鴨並不重要。鴨子類型指導我們只關注對象的行為,而不關注對象本身,也就是關注HAS-A, 而不是IS-A。

下面我們用代碼來類比這個故事。

var duck = { duckSinging: function(){ console.log( ‘嘎嘎嘎‘ ); } }; var chicken = { duckSinging: function(){ console.log( ‘嘎嘎嘎‘ ); } }; var choir = []; //合唱團 var joinChoir = function( animal ){ if ( animal && typeof animal.duckSinging === ‘function‘ ){ choir.push( animal ); console.log( ‘恭喜加入合唱團‘ ); console.log( ‘合唱團已有成員數量:‘ + choir.length ); } }; joinChoir( duck ); //恭喜加入合唱團 joinChoir( chicken ); //恭喜加入合唱團

我們看到,對於加入合唱團的動物,大臣們根本無需檢查它們的類型,而是只需要保證它們擁有duckSinging方法。如果下次期望加入合唱團的是一隻小狗,而這隻小狗剛好也會鴨子叫,我相信這隻小狗也能順利加入。

在動態類型語言的物件導向設計中,鴨子類型的概念至關重要。利用鴨子類型的思想,我們不必藉助超類型的協助,就能輕鬆地在動態類型語言中實現一個原則:“面向介面編程,而不是面向實現編程”。例如,一個對象若有push和pop方法,並且這些方法提供了正確的實現,它就可以被當作棧來使用。一個對象如果有length屬性,也可以依照下標來存取屬性(最好還要擁有slice和splice等方法),這個對象就可以被當作數組來使用。

在靜態類型語言中,要實現“面向介面編程”並不是一件容易的事情,往往要通過抽象類別或者介面等將對象進行向上轉型。當對象的真正類型被隱藏在它的超類型身後,這些對象才能在類型檢查系統的“監視”之下互相被替換使用。只有當對象能夠被互相替換使用,才能體現出對象多態性的價值。

“面向介面編程”是設計模式中最重要的思想,但在JavaScript語言中,“面向介面編程”的過程跟主流的靜態類型語言不一樣,因此,在JavaScript中實現設計模式的過程與在一些我們熟悉的語言中實現的過程會大相徑庭。


本文摘自《JavaScript設計模式與開發實踐?》

JavaScript王國裡的鴨子合唱團

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.