征服Ajax-Web2.0開發技術詳解試讀版

JavaScript 面向對象程序設計


一、JavaScript 中支持面向對象的基礎


1.在JavaScript中,函數和類就是一個概念,當new一個函數時,就會返回一個對象。如果這個函數中沒有初始化類成員,那就會返回一個空的對象。


2.在JavaScript中,每個對象可以看作是多個屬性(方法)的集合,引用一個屬性(方法)
很簡單,即:
對象名.屬性(方法)名
除此之外,還可以用方括號的形式來引用:
對象名[“屬性(方法)名”]
3.在其他語言中,對象一旦生成,就不可更改了,要爲一個對象添加修改成員必須要在對應的類中修改,並重新實例化,而且程序必須經過重新編譯。JavaScript 中卻非如此,它提供了靈活的機制來修改對象的行爲,可以動態添加、修改、刪除屬性和方法。


4.傳統的面嚮對象語言中,每個對象都會對應到一個類。而上一節講this 指針時提到,JavaScript 中的對象其實就是屬性(方法)的一個集合,並沒有嚴格意義的類的概念。所以它提供了另外一種簡單的方式來創建對象,即大括號({})語法:
{
property1:statement,
property2:statement2,
…,
propertyN:statmentN
}
通過大括號括住多個屬性或方法及其定義(這些屬性或方法用逗號隔開),來實現對象的定義,這段代碼就直接定義個了具有n個屬性或方法的對象,其中屬性名和其定義之間用冒號(:)隔開。


5.prototype 對象是實現面向對象的一個重要機制。每個函數(function)其實也是一個對象,它們對應的類是“Function”,但它們身份特殊,每個函數對象都具有一個子對象prototype。顧名思義,prototype 表示了該函數的原型,而函數也即是類,prototype 實際上就是表示了一個類的成員的集合。當通過new 來獲取一個類的對象時,prototype 對象的成員都會成爲實例化對象的成員。


二、深入認識JavaScript 中的函數


1.
function funcName(){
//函數體
}
//等價於
var funcName=function(){
//函數體
}
但前面一種方式創建的是有名函數,而後面是創建了一個無名函數,只是讓一個變量指向了這個無名函數。在使用上僅有一點區別,就是:對於有名函數,它可以出現在調用之後再定義;而對於無名函數,它必須是在調用之前就已經定義。


2.Function是所有函數對象的基礎,而Object則是所有對象(包括函數對象)的基礎。在JavaScript中,任何一個對象都是Object的實例,因此,可以修改Object這個類型來讓所有的對象具有一些通用的屬性和方法,修改Object類型是通過prototype來完成的。


3.傳遞給函數的隱含參數:arguments
因此,在定義函數的時候,即使不指定參數列表,仍然可以通過arguments 引用到所獲得的參數,這給編程帶來了很大的靈活性。arguments對象的另一個屬性是callee,它表示對函數對象本身的引用,這有利於實現無名函數的遞歸或者保證函數的封裝性,例如使用遞歸來計算1 到n的自然數之和:
var sum=function(n){
if(1==n)return 1;
else return n+sum(n-1);
}
alert(sum(100));
其中函數內部包含了對sum自身的調用,然而對於JavaScript來說,函數名僅僅是一個變量名,在函數內部調用sum即相當於調用一個全局變量,不能很好的體現出是調用自身,所以使用arguments.callee屬性會是一個較好的辦法:
var sum=function(n){
if(1==n)return 1;
else return n+arguments.callee(n-1);
}
alert(sum(100));


4.JavaScript爲函數對象定義了兩個方法:apply和call,它們的作用都是將函數綁定到另外一個對象上去運行,兩者僅在定義參數的方式有所區別:
Function.prototype.apply(thisArg,argArray);
Function.prototype.call(thisArg[,arg1[,arg2…]]);


與 arguments 的length屬性不同,函數對象的還有一個參數相關的屬性length,它表示函數定義時所指定參數的個數,而非調用時實際傳遞的參數個數。例如下面的代碼將顯示2:
function sum(a,b){
return a+b;
}
alert(sum.length);


5.JavaScript中對象的本質:一個對象就是由一個或多個屬性(方法)組成的集合。每個集合元素不是僅能屬於一個集合,而是可以動態的屬於多個集合。這樣,一個方法(集合元素)由誰調用,this指針就指向誰。


三、類的實現


1.儘管前面介紹瞭如何定義一個類,如何初始化一個類的實例,但既可以在function定義的函數體中添加成員,又可以用prototype 定義類的成員,代碼顯的很混亂,和面嚮對象語言類的實現之間有着很大的區別。那麼,如何以一種清晰的方式來定義類呢?下面給出了一種類的實現模式,並將它們對應到面嚮對象語言類的實現上。
類的構造函數用來初始化一個實例,是每個類必不可少的一部分。在傳統意義的面向對象中,類的構造函數的名稱和類的名稱一致,同時它們的定義方式和類成員的定義是類似而又相互獨立的。而在JavaScript中,由於對象的靈活的性質,在構造函數中也可以爲類添加成員,在增加靈活性的同時,也增加了代碼的複雜度。爲了提高代碼的可讀性和開發效率,完全可以拋棄這種定義成員的方式,而使用prototype 對象來替代,這樣function 的定義就是類的構造函數,符合傳統意義類的實現:類名和構造函數名是相同的。


四、公有成員、私有成員和靜態成員


1.私有成員即在類的內部實現中可以共享的成員,但是並不對外公開。JavaScript 中並沒有特殊的機制來定義私有成員,但可以用一些技巧來實現這個功能。


2.這個技巧主要是通過變量的作用域性質來實現的,在JavaScript中,一個函數內部定義的變量稱爲局部變量,該變量不能夠被函數外的程序所訪問,卻可以被函數內部定義的嵌套函數所訪問。在實現私有成員的過程中,正是利用了這一性質。


五、使用for(…in…)實現反射機制


1.反射機制指的是程序在運行時能夠獲取自身的信息。例如一個對象能夠在運行時知道自己有哪些方法和屬性,這屬於高級的面向對象程序設計的功能。在C#中,利用程序集中的元數據來實現反射,能夠在運行時動態判斷和調用自己的屬性或方法。


六、類的繼承


1.在JavaScript 中,除了基本的數據類型(數字、字符串、布爾等),所有的賦值以及函數參數都是引用傳遞,而不是值傳遞。


2.前面一節介紹的共享prototype 來實現類的繼承,並不是一種很好的方法,畢竟兩個類是共享的一個prototype,任何對成員的重定義都會互相影響,不是嚴格意義的繼承。但在這個思想的基礎上,可以利用反射機制來實現類的繼承,思路如下:利用for(…in…)語句枚舉出所有基類prototype的成員,並將其賦值給子類的prototype對象。


七、實現抽象類


1.虛函數是類成員中的概念,即只做了一個聲明而未實現的方法,具有虛函數的類就稱之爲抽象類,這些虛函數在派生類中才被實現。抽象類是不能實例化的,因爲其中的虛函數並不是一個完整的函數,不能被調用。所以抽象類一般只作爲基類被派生以後再使用。
和類的繼承一樣,JavaScript 並沒有任何機制用於支持抽象類,其實繼承都沒有,更何況抽象類了。但利用JavaScript語言本身的性質,可以實現自己的抽象類。


2.解釋型語言執行的特點,它們只有在運行到某一個方法調用時,纔會檢查該方法是否存在,而不會向編譯型語言一樣在編譯階段就檢查方法存在與否。JavaScript 中則避免了這個問題。當然,如果希望在基類中添加虛方法的一個定義,也是可以的,只要在派生類中覆蓋此方法即可。


八、事件設計模式


1.事件機制可以使程序邏輯更加符合現實世界,在JavaScript中很多對象都有自己的事件,例如按鈕就有onclick事件,下拉列表框就有onchange事件,通過這些事件可以方便編程。那麼對於自己定義的類,是否也實現事件機制呢?答案是肯定的,通過事件機制,可以將類設計爲獨立的模塊,通過事件對外通信,提高了程序的開發效率。


九、實例:使用面向對象思想處理cookie


1.對於cookie 的處理,事實上只是封裝一些方法,每個對象不會有狀態,所以不需要創建一個cookie 處理類,而只用一個全局對象來聯繫這些cookie 操作。對象名可以理解爲命名空間。




JavaScript 高級技術


一、框架間的互相引用


1.一個頁面中的所有框架以集合的形式作爲window 對象的屬性提供,例如:
window.frames 就表示該頁面內所有框架的集合,這和表單對象、鏈接對象、圖片對象等是類似的,不同的是,這些集合是document 的屬性。因此,要引用一個子框架,可以使用如下語法:
window.frames[“frameName”];
window.frames.frameName
window.frames[index]
其中,window字樣也可以用self代替或省略,假設frameName 爲頁面中第一個框架,則以下的寫法是等價的:
self.frames[“frameName”]
self.frames[0]
frames[0]
frameName


二、改變框架的載入頁面


1.前面已經講到,對框架的引用就是對window對象的引用,利用window對象的location屬性,可以改變框架的導航,例如:
window.frames[0].location=”1.html”;


三、引用其他框架內的JavaScript變量和函數


1.框架可以使一個頁面劃分爲功能獨立的多個模塊,每個模塊之間彼此獨立,但又可以通過window 對象的引用來建立聯繫,是web 開發中的一個重要機制。在Ajax 開發中,還可以利用隱藏框架實現各種技巧,在後面介紹Ajax 實例編程時可以發現,無刷新上傳文件以及解決Ajax的前進後退問題都會用到這種技術。




使用cookie


一、cookie概述


準確的說,cookie是瀏覽器提供的一種機制,它將document對象的cookie屬性提供給JavaScript。可以由JavaScript對其進行控制,而並不是JavaScript本身的性質。簡單的來講,cookie是存於用戶硬盤的一個文件,這個文件通常對應於一個域名,當瀏覽器再次訪問這個域名時,便使這個cookie 可用。因此,cookie 可以跨越一個域名下的多個網頁,但不能跨越多個域名使用。


cookie機制將信息存儲於用戶硬盤,因此可以作爲全局變量,這是它最大的一個優點。
一般來講,它可以用於以下幾種場合:
a.保存用戶登錄狀態。例如將用戶id 存儲於一個cookie 內,這樣當用戶下次訪問該頁面時就不需要重新登錄了,現在很多論壇和社區都提供這樣的功能。cookie還可以設置過期時間,當超過時間期限後,cookie就會自動消失。因此,系統往往可以提示用戶保持登錄狀態的時間:常見選項有一個月、三個月、一年等。
b.跟蹤用戶行爲。例如一個天氣預報網站,能夠根據用戶選擇的地區顯示當地的天氣情況。如果每次都需要選擇所在地是煩瑣的,當利用了cookie 後就會顯得很人性化了,系統能夠記住上一次訪問的地區,當下次再打開該頁面時,它就會自動顯示上次用戶所在地區的天氣情況。因爲一切都是在後臺完成,所以這樣的頁面就像爲某個用戶所定製的一樣,使用起來非常方便。
c.定製頁面。如果網站提供了換膚或更換佈局的功能,那麼可以使用cookie 來記錄用戶的選項,例如:背景色、分辨率等。當用戶下次訪問時,仍然可以保存上一次訪問的界面風格。
d.創建購物車。正如在前面的例子中使用cookie 來記錄用戶需要購買的商品,在結帳的時候可以統一提交。例如淘寶網就使用cookie記錄了用戶曾經瀏覽過的商品,方便隨時進行比較。


當然,上述應用僅僅是cookie 能完成的部分應用,還有更多的功能需要全局變量。任何事情都有正反兩面,cookie也不例外,它的缺點主要集中於安全性和隱私保護。主要包括以下幾種:
a.cookie 可能被禁用。當用戶非常注重個人隱私保護時,他很可能禁用瀏覽器的cookie功能。
b.cookie是瀏覽器相關的。這意味着即使訪問的是同一個頁面,不同瀏覽器之間所保存的cookie也是不能互相訪問的。
c.cookie 可能被刪除。因爲每個cookie 都是硬盤上的一個文件,因此很有可能被用戶刪除。
d.cookie 安全性不夠高。所有的cookie 都是以純文本的形式記錄於文件中,因此如果要保存用戶名密碼等信息時,最好事先經過加密處理。


二、綜合示例:構造通用的cookie處理函數


cookie 的處理過程比較複雜,但都具有一定的相似性。因此可以定義幾個函數來完成cookie的通用操作,從而實現代碼的複用。下面列出了常用的cookie操作及其函數實現。
1.添加一個cookie:addCookie(name,value,expireHours)
該函數接收3 個參數:cookie 名稱,cookie 值,以及在多少小時後過期。這裏約定 expireHours爲0 時不設定過期時間,即當瀏覽器關閉時cookie自動消失。該函數實現如下:
<script language="JavaScript" type="text/javascript">
<!--
function addCookie(name,value,expireHours){
var cookieString=name+"="+escape(value);
//判斷是否設置過期時間
if(expireHours>0){
var date=new Date();
date.setTime(date.getTime+expireHours*3600*1000);
cookieString=cookieString+"; expire="+date.toGMTString();
}
document.cookie=cookieString;
}
//-->
</script>
2.獲取指定名稱的cookie值:getCookie(name)
該函數返回名稱爲name的cookie值,如果不存在則返回空,其實現如下:
<script language="JavaScript" type="text/javascript">
<!--
function getCookie(name){
var strCookie=document.cookie;
var arrCookie=strCookie.split("; ");
for(var i=0;i<arrCookie.length;i++){
var arr=arrCookie[i].split("=");
if(arr[0]==name)return arr[1];
}
return "";
}
//-->
</script>
3.刪除指定名稱的cookie:deleteCookie(name)
該函數可以刪除指定名稱的cookie,其實現如下:
<script language="JavaScript" type="text/javascript">
<!--
function deleteCookie(name){
var date=new Date();
date.setTime(date.getTime()-10000);
document.cookie=name+"=v; expire="+date.toGMTString();
}
//-->
</script>


三、使用正則表達式


javaScript search和indexOf方法不同,該方法接收的是一個正則表達式,而indexOf只能接收一個字符串。但兩者的行爲是類似的。


四、使用window對象


1.使用定時器實現JavaScript的延期執行或重複執行
window 對象提供了兩個方法來實現定時器的效果,分別是window.setTimeout()和window.setInterval。其中前者可以使一段代碼在指定時間後運行;而後者則可以使一段代碼每過指定時間就運行一次。它們的原型如下:
window.setTimeout(expression,milliseconds);
window.setInterval(expression,milliseconds);
其中,expression可以是用引號括起來的一段代碼,也可以是一個函數名,到了指定的時間,系統便會自動調用該函數,當使用函數名作爲調用句柄時,不能帶有任何參數;而使用字符串時,則可以在其中寫入要傳遞的參數。兩個方法的第二個參數是milliseconds,表示延時或者重複執行的毫秒數


如果在延時期限到達之前取消延時執行,可以使用window.clearTimeout(timeoutId)方法,該方法接收一個id,表示一個定時器。這個id是由setTimeout方法返回。


如果想要取消定時執行,和clearTimeout 方法類似,可以調用window.clearInterval 方法。clearInterval 方法同樣接收一個setInterval方法返回的值作爲參數。


五、使用alert、prompt和confirm語句與用戶進行交互




異常處理


一、使用try-catch-finally處理異常
用戶可以使用該結構處理可能發生異常的代碼,如果發生異常,則由catch捕獲並進行處理,其語法如下:
try{
//要執行的代碼
}
catch(e){
//處理異常的代碼
}
finally{
//無論異常發生與否,都會執行的代碼
}


參考文檔:
http://www.w3school.com.cn/jsref/jsref_obj_global.asp
http://larrycaiyu.com
http://www.blogjava.net/eamoi
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章