JavaScript設計模式第一章:神奇的JavaScript(一)

來源:互聯網
上載者:User

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

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

/* Start and stop animations using functions. */
function startAnimation() {

}
function stopAnimation() {

}

      這種方法非常簡單,但它沒有建立一個動畫的對象來使你可以儲存狀態並擁有一些只作用於其內部狀態的方法。下面這段代碼定義了一個類使你可以建立這樣的一個對象:
/* Anim class. */
var Anim = function() {

};
Anim.prototype.start = function() {

};
Anim.prototype.stop = function() {

};
/* Usage. */
var myAnim = new Anim();
myAnim.start();

myAnim.stop();

      這裡定義了一個叫做Anim的類並為該類的prototype屬性增加了兩個方法。我們在第三章將詳細討論這種技術。如果你喜歡建立一個只有一個聲明的類,你可能會寫出如下的代碼:
/* Anim class, with a slightly different syntax for declaring methods. */
var Anim = function() {

};
Anim.prototype = {
start: function() {

},

stop: function() {

}
};

      這看起來有點類似於經典的物件導向編程風格:將函式宣告嵌套在一個類聲明之內。如果你之前使用過這種風格,你可以試一下下面這個例子,如果不太理解下面的部分代碼也不要擔心:
/* Add a method to the Function object that can be used to declare methods. */
Function.prototype.method = function(name, fn) {
    this.prototype[name] = fn;
};
/* Anim class, with methods created using a convenience method. */
var Anim = function() {

};
Anim.method(start, function() {

});
Anim.method(stop, function() {

});

      Function.prototype.method使你可以為類增加新的方法。它可以接收兩個參數:第一個是作為新方法的名字的字串,第二個是為這個方法名指定的一個函數。
你可以通過對Function.prototype.method稍作修改以使其可以進行鏈式調用。為此,你只需要在建立完每個方法時返回一個this即可。我們在第6章將討論鏈:
/* This version allows the calls to be chained. */
Function.prototype.method = function(name, fn) {
    this.prototype[name] = fn;
    return this;
};
/* Anim class, with methods created using a convenience method and chaining. */
var Anim = function() {

};
Anim.
method(start, function() {

}).
method(stop, function() {

});

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

一種弱類型的語言
      在JavaScript中,在定義變數時不需要定義類型,但是這並不意味著它沒有變數類型。一個變數可以儲存多種資料類型的資料,其類型取決所賦予給它的資料。JS有三種基本的資料類型:布爾型、數字型和字串型(JavaScript不同於其他的程式設計語言,它將整型和浮點型作為同一種類型),此外,它含有可執行代碼的function(函數)類型,還有包含複合類型的對象(Object)類型(Array是一種特殊的對象,它包含一些有序的資料集合)。現在,它還有null和undefiend資料類型。基礎資料型別 (Elementary Data Type)按值傳遞,其它的資料類型是按照引用傳遞,因此如果你不小心就可能導致一些意外的問題。
      和其它弱類型語言一樣,變數會根據被賦予的值改變其資料類型。基礎資料型別 (Elementary Data Type)之間可以互相轉換,toString方法可以將一個數字或布爾型資料轉換為一個字串。parseFloat和floatInt函數可以將字串轉換為數字型,雙否定號可以將一個字串或數字資料轉換成布爾類型。
      var bool = !!num;
      弱類型的變數提供了很多了靈活性,你不需要擔心資料類型錯誤,因為在需要的時候JavaScript會自動做轉換。

函數是第一型對象
      在JavaScript語言中,函數是第一性的對象。它可以被儲存在一個變數中,作為參數傳入到函數中,被函數作為傳回值返回,或者在啟動並執行時間動態構造。這些特性使你在使用函數增加了很大的靈活性和表現能力。在本書後面的部分你會看到,這些特性是你構建一個傳統的物件導向架構的基礎。
      你可以使用functiuon(){…}方法建立一個匿名的函數。它沒有函數名但可以被賦給一個變數。下面是一個匿名函數的例子:
/* An anonymous function, executed immediately. */
(function() {
    var foo = 10;
    var bar = 2;
    alert(foo * bar);
})();

      這個函數在定義和執行時沒有賦給任何變數。最後的一對括弧會使該函數立即執行。但並一定只能這樣寫:
/* An anonymous function with arguments. */
(function(foo, bar) {
    alert(foo * bar);
})(10, 2);

      這個匿名函數和第一個基本相同,但這個函數沒有使用var在內部定義變數,而是作為參數傳入了函數,這個函數可以有一個傳回值並可以被賦予給一個變數。
/* An anonymous function that returns avalue. */
var baz = (function(foo, bar) {
    return foo * bar;
})(10, 2);
// baz will equal 20.

      匿名函數的一個最有趣的功能就是建立閉包。閉包就是通過使用嵌套函數,建立一個保護變數空間。JavaScript有函數級的範圍,也就是說在函數中定義的變數不能被外部存取。它還有文法上範圍,也就是函數運行在他們定義的範圍而不是他們執行時的範圍。這兩者相結合使你可以通過匿名函數建立一個保護變數。你可以使用這點為類建立私人變數。
/* An anonymous function used as aclosure. */
var baz;
(function() {
    var foo = 10;
    var bar = 2;
    baz = function() {
    return foo * bar;
};
})();
baz(); // baz can access foo and bar, even though it is executed outside of the
// anonymous function.

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.