javascript設計模式

轉載:http://chinazblz.blog.163.com/blog/static/939391732010519113754712/

第一章 神奇的JavaScript

      JavaScript是近年來一個非常流行並被廣泛應用的語言。因爲它被幾乎所有的瀏覽器所支持,因此也得到了廣泛的推廣。作爲一種語言,它在我們的生活變得難以相信的重要,幫助我們增強web的功能,創建豐富的用戶界面。
爲什麼仍然有一些人認爲它是一種“玩具式”的語言,認爲它不適合於專業的程序員。我認爲這是因爲他們沒有認識到它的真正的強大之處和它相比其它各種編程語言的獨特性。JavaScript是一門非常神奇高深的語言,擁有一些C家族類語言所沒有的特性。
本章我們將探討是哪些特性使JavaScript如此的神奇高深。我們將看到JavaScript使你可以用多種不同的方式來完成同一件事情,以及如何通過函數式程序設計的方式來模擬實現面向對象程序設計。我們將討論爲什麼你應該把設計模式放在首頁以及如何使用它來使你的代碼更有效,工作更簡單。

靈活的JavaScript
      JavaScript 的一個很重要的特性就是其靈活性。作爲JavaScript程序員,你可以使你的程序很簡單或很複雜。JavaScript允許你使用各種不同的編程風格。你可以使用函數式風格或者接近於面向對象的編程風格來編寫你的代碼,同樣你可以在不瞭解函數式或面向對象編程的情形下書寫相對複雜的程序,你也可以通過寫一些簡單的函數來使用它。或者這些也是一些人把JavaScript看做“玩具”語言的一個原因,但我們應該認爲這些是一些優秀的特性。它可以使程序員只掌握小部分易學的語言子集來完成一些有用的功能,同樣它也意味着當你成爲一個更加高級的程序員時JavaScript會在你手中發揮更大的能力。
      JavaScript允許你去模擬其他語言中的模式和思想。此外它自身還包含一些獨有的特性。它提供了和傳統服務端語言完全一樣的面向對象特性。
      我們來看一下通過幾個不同的代碼組織方式來完成同樣的一件任務:啓動和停止一個動畫。如果你不理解這些例子也無所謂,我們這裏使用的所有模式和技術都會在本書中講到。現在,你可以把這一節做爲JavaScript可以通過不同的方式來完成同一件任務的一個實際的例子。
      如果你以前是一個面向過程的程序員,你可以會像下面這樣做:


      你剛剛看到了我們使用五種略微不同的方式來完成了同樣一件任務。根據你的編程背景,你可能覺得某種方式比其他一種更好。這其實很好,JavaScript允許你使用最適合你們手中項目的編程方式。每種方式擁有不同的特點和不同代碼量,效率和性能。我們在本書的第一部分涵蓋了所有的這些編程方式。

一種弱類型的語言      在JavaScript中,在定義變量時不需要定義類型,但是這並不意味着它沒有變量類型。一個變量可以保存多種數據類型的數據,其類型取決所賦予給它的數據。JS有三種基本的數據類型:布爾型、數字型和字符串型(JavaScript不同於其他的編程語言,它將整型和浮點型作爲同一種類型),此外,它含有可執行代碼的function(函數)類型,還有包含複合類型的對象(Object)類型(Array是一種特殊的對象,它包含一些有序的數據集合)。現在,它還有null和undefiend數據類型。基本數據類型按值傳遞,其它的數據類型是按照引用傳遞,因此如果你不小心就可能導致一些意外的問題。      和其它弱類型語言一樣,變量會根據被賦予的值改變其數據類型。基本數據類型之間可以互相轉換,toString方法可以將一個數字或布爾型數據轉換爲一個字符串。 parseFloat和floatInt函數可以將字符串轉換爲數字型,雙否定號可以將一個字符串或數字數據轉換成布爾類型。      var bool = !!num;      弱類型的變量提供了很多了靈活性,你不需要擔心數據類型錯誤,因爲在需要的時候JavaScript會自動做轉換。函數是第一型對象      在 JavaScript語言中,函數是第一性的對象。它可以被存儲在一個變量中,作爲參數傳入到函數中,被函數作爲返回值返回,或者在運行的時間動態構造。這些特性使你在使用函數增加了很大的靈活性和表現能力。在本書後面的部分你會看到,這些特性是你構建一個傳統的面向對象框架的基礎。      你可以使用functiuon(){…}方法創建一個匿名的函數。它沒有函數名但可以被賦給一個變量。下面是一個匿名函數的例子:

      這個函數在定義和執行時沒有賦給任何變量。最後的一對括號會使該函數立即執行。但並一定只能這樣寫:

      這個匿名函數和第一個基本相同,但這個函數沒有使用var在內部定義變量,而是作爲參數傳入了函數,這個函數可以有一個返回值並可以被賦予給一個變量。

      匿名函數的一個最有趣的功能就是創建閉包。閉包就是通過使用嵌套函數,創建一個保護變量空間。JavaScript有函數級的作用域,也就是說在函數中定義的變量不能被外部訪問。它還有語法上作用域,也就是函數運行在他們定義的作用域而不是他們執行時的作用域。這兩者相結合使你可以通過匿名函數創建一個保護變量。你可以使用這點爲類創建私有變量。

      變量foo和bar只在匿名函數中定義,因爲baz函數也定義在這個閉包中,因此它可以訪問這兩個變量,甚至在閉包函數執行結束之後。這是我們整本書都會一直接觸的一個複雜邏輯。我們在第三章討論封裝的時候將詳細講解這種技術。

原文轉自:http://wanghongxu.javaeye.com/blog/434997

更多相關資料:

http://www.riabook.cn/doc/designpattern/

http://ued.alipay.com/2009/10/javascript-design-pattern/

 

Javascript代碼
  1. /* Start and stop animations using functions. */  
  2. function startAnimation() {  
  3.   
  4. }  
  5. function stopAnimation() {  
  6.   
  7. }  



      這種方法非常簡單,但它沒有創建一個動畫的對象來使你可以保存狀態並擁有一些只作用於其內部狀態的方法。下面這段代碼定義了一個類使你可以創建這樣的一個對象:
 

Javascript代碼
  1. /* Anim class. */  
  2. var Anim = function() {  
  3.   
  4. };  
  5. Anim.prototype.start = function() {  
  6.   
  7. };  
  8. Anim.prototype.stop = function() {  
  9.   
  10. };  
  11. /* Usage. */  
  12. var myAnim = new Anim();  
  13. myAnim.start();  
  14.   
  15. myAnim.stop();  


      這裏定義了一個叫做Anim的類併爲該類的prototype屬性增加了兩個方法。我們在第三章將詳細討論這種技術。如果你喜歡創建一個只有一個聲明的類,你可能會寫出如下的代碼:
 

Javascript代碼
  1. /* Anim class, with a slightly different syntax for declaring methods. */  
  2. var Anim = function() {   
  3.   
  4. };  
  5. Anim.prototype = {  
  6. start: function() {  
  7.   
  8. },  
  9.   
  10. stop: function() {  
  11.   
  12. }  
  13. };  



      這看起來有點類似於經典的面向對象編程風格:將函數聲明嵌套在一個類聲明之內。如果你之前使用過這種風格,你可以試一下下面這個例子,如果不太理解下面的部分代碼也不要擔心:
 

Javascript代碼
  1. /* Add a method to the Function object that can be used to declare methods. */  
  2. Function.prototype.method = function(name, fn) {  
  3.     this.prototype[name] = fn;  
  4. };  
  5. /* Anim class, with methods created using a convenience method. */  
  6. var Anim = function() {   
  7.   
  8. };  
  9. Anim.method('start', function() {  
  10.   
  11. });  
  12. Anim.method('stop', function() {  
  13.   
  14. });  


      Function.prototype.method使你可以爲類增加新的方法。它可以接收兩個參數:第一個是作爲新方法的名字的字符串,第二個是爲這個方法名指定的一個函數。
你可以通過對Function.prototype.method稍作修改以使其可以進行鏈式調用。爲此,你只需要在創建完每個方法時返回一個this即可。我們在第6章將討論鏈:
 

Javascript代碼
  1. /* This version allows the calls to be chained. */  
  2. Function.prototype.method = function(name, fn) {  
  3.     this.prototype[name] = fn;  
  4.     return this;  
  5. };  
  6. /* Anim class, with methods created using a convenience method and chaining. */  
  7. var Anim = function() {   
  8.   
  9. };  
  10. Anim.  
  11. method('start', function() {  
  12.   
  13. }).  
  14. method('stop', function() {  
  15.   
  16. });  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章