當前,Javascript已經成為世界上最受歡迎和被廣泛應用的的程式設計語言--因為他被捆綁到各種瀏覽器中。作為一種程式設計語言,它已經滲透到人們的日常生活中,它為我們訪問的網站帶來了更加好的使用者體驗。
很多人很輕視JavaScrpt--它只是玩具,成為一個專業的JavaScript Programmer很不值得. 我想是因為那些人還沒有意識到JavaScirpt強大的能力和在編程世界的不可代替性。JavaScript 是一門很鬆散,靈活的程式設計語言,有很多特徵與C 家族不一樣。
接下來,我們一起去探究一下JavaScirpt的靈活性---用數種不同的方法去實現相同的功能。當然,我還會和大家分享如果從面向過程編程轉變到物件導向編程。我們還會探討為什麼我們優先選擇用設計模式和怎麼把設計模式融入到JavaScirpt當中。
JavaScript的可擴充性:
可擴充性是一門強大的程式設計語言的標誌。作為一名Javascipt 開發人員,我們可以用簡單方法或者複雜的方法來構建應用—It’s up to you.JavaScirpt 也存在很多種編程風格,你可以用簡單的函數方式或者更複雜的物件導向方法,這是為什麼很多人認為javascript是玩具的原因。
我們可以用JavaScript去模仿其他程式設計語言的模式與風格。當然,我們完成可以模仿Server-Side 的物件導向程式設計語言的風格。
下以開始和停止動畫作為例子,看看怎麼用不同的方法去實現同樣的功能:
面向過程編程方式:
/*Start and stop animation using functions*/function startAnimation(){ ......................}function stopAnimation(){.........................}
這種實現方式很簡單,但是它不允許你建立Animation對象來保持動畫的狀態(屬性)和行為(方法)。接下來我們用物件導向的方式來解決這一問題:
/**Animation Class**/var Animation=function(){........};Animation.prototye.start=function(){........};Animation.prototype.stop=function(){..........};/*Demo*/var Anim=new Animation();Anim.start();.........Anim.stop();
上面,我們定義了一個類叫Animation,它持有兩種不同的行為,strat,stop。如果我們更希望把方法都集中地聲明,我們可以用下面的方式:
/**Animation class**/var Animation=function(){...............};Animation.prototype={ start:{.........},stop:{........}};
對於使用Java,C#等物件導向編程的開發人員,這種編程豐富應該有種似曾相識的感覺吧---類聲明-->方法在類中聲明。下面我們再把代碼改進一下,讓風格更貼近物件導向的風格:
/*Add a method to the Function object that can be use to declare method...*/Function.prototype.method=function(name,fn){ this.prototype[name]=fn;};/*Animation Class*/var Animation=function(){............};Animation.method("start",function(){............});Animation.method("stop",function(){...............});
Function.protoype.method(fnName,fn) 讓我們可以在所有的JavaScript類中添加方法。第一個參數是要添加方法的名字,第二個方法是要添加方法的函數體。
最後,我們可以把Funtion.prototype.method方法改進一下,讓它實作類別型與jQuery的鏈式調用:
/*Add a method to the Function object that can be use to declare method...*/Function.prototype.method=function(name,fn){ this.prototype[name]=fn; return this;};/*Animation Class*/var Animation=function(){............};/*Clain call*/Animation.method("start",function(){............}).method("stop",function(){...............});
相信,通過上面的例子,大家應該慢慢體會到JavaScript可擴充性和靈活性的強大魅力了吧。
鬆散的(loosely-typed)程式設計語言
在JavaScript 使用過程中,我們不需聲明變數的類型,但是不代表該變數沒有類型。根據變數中裝載的資料不同,變數可以是幾中類型。
基本的3種類型:Booleans,Numbers,String.(JavaScript 把整型與浮點型當中同一種類型).
function,它包含一段可執行檔代碼。這裡還有對象(object),它可以包含多種資料類型在其中,如Array。
null與undefined這兩種資料類型。
基本類型是值傳遞的,而其他類型是通過引用(指標,地址)傳遞的,這一點很重要,如果不清楚這點,在編程過程中可能引起不可預知的問題。
函數--特殊的對象
在JavaScript的程式設計語言中,函數是特殊的對象。它們能夠儲存在變數中,也可以以參數的形式傳遞到另一個函數中,也可以作為函數的傳回值。這些特徵為JavaScript帶來極大擴充性和豐富的表達方法。
例如,你可以用function(){…}建立匿名函數,它沒有指定函數名,但是它可以任意賦值給其他變數,看下面簡單的例子:
/*Anonymous function,execude immediately*/(function(){ var price=1.2; var number=10; alert(price*number) })();
上面的這個函數在沒有賦值到變數就已經定義和執行了,代碼最後的括弧聲明了這個函數立刻執行。我們看到括弧中沒有任何參數,但是,我們也可以定義參數,這樣,匿名函數就可以獲得這些參數,看下面代碼例子:
/**An anonymous function with argument**/(function(){ alert(price*number)})(price,number);
當然,匿名函數還可以作為傳回值,看下面例子:
var totalPrice=(function(){ return price*number;})(10,10);
// totalPrice=100
用匿名函數構造閉包(closure)
什麼是閉包?閉包簡單來說就是一塊受保護的地區,通過函數嵌套產生。JavaScript 有函數範圍的範圍,換句話說,定義在函數內部的變數外部不能訪問。有趣的JavaSript是函數是常量作用範圍,也就是說函數運行在它定義好的域中,而不是在運行在執行它的域。綜合這兩個特徵,我們就可以把我們要保護的變數放進匿名函數中。實際物件導向編程中,我們可以用這種方式為類建立私人變數,例子如下:
/*an anonymous function as closure*/var totalPrice;(funciton{ var price=10; var number=10; totalPrice=function(){ price*number;};})();//totalPrice();
從上例看出,即使totalPrice 在匿名函數外部,它也可以訪問 price 和 number.更複雜的問題,我們會在後面的文章中繼續探討閉包的應用.
對象可變動性
在JavaScirpt的世界中,任何東西都是對象(除了三種基本的資料類型外)。而且,更有趣的是,所有對象都是可以隨機改變的。這些特徵可以賦予Javascript 其他語言沒有的能力,如動態添加屬性:
function logTarce(){ LogTrce.timer++; alert("Log trace...");}LogTrace.timer=0;
這意味著我們可以在類定義後修改類,或者是對象初始化之前修改對象:
/*Class Person*/var Person=function(name,age){ this.name=name; this.age=age;}Person.protoytpe.getAge=function(){ return this.age;};Person.prototype.getName=function(){ return this.name;}/*instantiate the class*/var timo=new Person("timo",25);/*modify the class*/Person.prototype.sayWelcome=function(){ alert("Hi"+this.name+",welcome to timo.lee's tech blog");}/*modify the specific instance*/timo.helloTimo=function(){ alert("Hello Timo");};
在上面這些例子中,我們看到我們既可以在類定義後修改類,可以是對象執行個體化後修改對象。
關於繼承
相比與傳統的物件導向語言,JavaScript 不能直接地(聲明的方式)實現繼承。但是JavaScript 可以用基於對象(prototypal)的方式實現/類比繼承。
JavaScript 中使用設計模式
相信提起設計模式,大家都會想起gof(四人幫).設計模式只是一種經驗\模式,它可以在任何語言中實現,所有JavaScript也不例外,在往後的文章在,會和大家一起探討這個主題.
相信,大家都慢慢體驗到JavaScript的強大力量了吧.
welcome to contact with me:timo.li.icon@gmail.com