国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
在JavaScript中使用面向?qū)ο?/div>

原文地址:http://www.cnblogs.com/Truly/archive/2007/07/24/830013.html

前言

        OO(面向?qū)ο?概念的提出是軟件開發(fā)工程發(fā)展的一次革命,多年來(lái)我們借助它使得很多大型應(yīng)用程序得以順利實(shí)現(xiàn)。如果您還沒(méi)有掌握并使用OO進(jìn)行程序設(shè)計(jì)和開發(fā),那么您無(wú)疑還停留在軟件開發(fā)的石器時(shí)代。大多數(shù)編程語(yǔ)言,尤其是近年問(wèn)世的一些語(yǔ)言,都很好的支持了面向?qū)ο?,您可能?duì)此了如執(zhí)掌,但是一些語(yǔ)言在OO方面卻無(wú)法與其它高級(jí)語(yǔ)言相比,在這些語(yǔ)言上進(jìn)行面向?qū)ο蟪绦蛟O(shè)計(jì)和開發(fā)會(huì)有些困難,例如本文要討論的JavaScript。JavaScript是一門古老的語(yǔ)言,但是隨著近期Web2.0 技術(shù)的熱捧,這門語(yǔ)言又重新煥發(fā)出青春的光輝,借助于JavaScript客戶端技術(shù),我們的Web體驗(yàn)變得豐富而又精彩,為了設(shè)計(jì)和開發(fā)更加完善、復(fù)雜的客戶端應(yīng)用,我們必須掌握J(rèn)avaScript上的OO方法,這正是本文要討論的。 前幾天閱讀了MSDN的《使用面向?qū)ο蟮募夹g(shù)創(chuàng)建高級(jí) Web 應(yīng)用程序》一文,覺(jué)得還有些東西有必要繼續(xù)探討補(bǔ)充一下,就有了本文。

        目錄

        開始
        對(duì)象的聲明
        成員的聲明
        全局變量和局部變量
        命名空間

開始
JavaScript是一門相當(dāng)靈活的語(yǔ)言,語(yǔ)法也相當(dāng)寬松,并且入門門檻很低,您可以不費(fèi)什么力氣就編寫出一大堆可以運(yùn)行的代碼,但是根據(jù)我在實(shí)際工作中的經(jīng)驗(yàn),多數(shù)人還是對(duì)之核心技術(shù)知之甚少。同樣一個(gè)功能,簡(jiǎn)簡(jiǎn)單單幾行代碼,就可看出一個(gè)人的技術(shù)功底。正如天龍八部中的蕭峰使用的一招“太祖長(zhǎng)拳”,這是一種武術(shù)中的入門的招法,雖然它看上去很簡(jiǎn)單,但是在高手的使用下,卻是威力無(wú)窮。其實(shí)越是簡(jiǎn)單的東西,要把它變得完美就越是困難。所以作為能工巧匠的您怎能錯(cuò)過(guò)這篇文章?切聽我一一道來(lái)。

 

對(duì)象的聲明
在JavaScript我們可以使用下面幾種代碼進(jìn)行對(duì)象聲明:

Js代碼
  1. var MyObject = {};  

 

 

Js代碼
  1. function MyObject()   
  2. {   
  3.         blabalbla...   
  4. }  

 

 

Js代碼
  1. var MyObject = function(){balbalba...};  

對(duì)于后兩種方法,我們還可以增加參數(shù),這樣就類似于一個(gè)帶參數(shù)的構(gòu)造器了,例如:

Js代碼
  1. function MyObject(msg)   
  2. {   
  3.         alert(msg);   
  4. }   
  5.   
  6. var o = new MyObject("Hello world");   
  7.   
  8. var MyObject = function(msg)   
  9. {   
  10.       alert(msg + " again");   
  11. };   
  12.   
  13. var o = new MyObject("Hello world!");  

 

甚至我們可以使用字符串來(lái)生聲明函數(shù),這使得我們的程序更加靈活:

 

Js代碼
  1. /*  
  2.  * Function可以有多個(gè)入口參數(shù),最后一個(gè)參數(shù)最為方法體。  
  3.  */  
  4. var MyObject = new Function("msg","alert(msg);");   
  5.   
  6. var o = new MyObject("Hello world!");  

 

成員的聲明

在JavaScript中,要聲明一個(gè)對(duì)象的成員也非常簡(jiǎn)單,但是跟其它的高級(jí)程序仍然略有不同,請(qǐng)看下面的示例:

Js代碼
  1. var MyObject = {   
  2.       FirstName:"Mary",    
  3.       LastName:"Cook",   
  4.       Age:18,    
  5.       ShowFullName : function(){   
  6.      alert(this.FirstName + ' ' + this.LastName);   
  7.        }   
  8.   }   
  9.      
  10. MyObject.ShowFullName();  

 

或者使用字符串來(lái)聲明:

Js代碼
  1. var MyObject = {   
  2.       "FirstName":"Mary",    
  3.       "LastName":"Cook",   
  4.       "Age":18,    
  5.       "ShowFullName" : function(){   
  6.      alert(this.FirstName + ' ' + this.LastName);   
  7.        }   
  8.   }   
  9.      
  10. MyObject.ShowFullName();  

 

 

用字符串的聲明方式有諸多好處,這也是JavaScript中表示對(duì)象的一種特殊方式,像近年JSON概念的提出,將這種特殊方式提示到了一個(gè)新的高度,更多JSON的介紹請(qǐng)參加我以前的大作《深入淺出JSON》

而在實(shí)際的程序設(shè)計(jì)中,這種方式在JavaScript的面向?qū)ο蟪绦蛟O(shè)計(jì)中我們通常用來(lái)映射數(shù)據(jù)類型,定義類似高級(jí)語(yǔ)言中的結(jié)構(gòu),集合,實(shí)體等,還常常用作定義靜態(tài)幫助器類,無(wú)需構(gòu)造而可以直接訪問(wèn)成員方法。例如上面代碼中的MyObject.ShowFullName();

前面我們介紹了成員的定義,在JavaScript中另一個(gè)面向?qū)ο筇攸c(diǎn)是我們可以像高級(jí)編程語(yǔ)言一樣使用.和[]引用成員,如:

Js代碼
  1. var DateTime = { Now : new Date(), "Show" : function() { alert(new Date());} };   
  2.   
  3. alert(DateTime.Now);   
  4. // 等價(jià)于:   
  5. alert(DateTime["Now"]);   
  6.   
  7. DateTime.Show()   
  8. // 等價(jià)于:   
  9. DateTime["Show"]();  

 

提到方法調(diào)用,這里有一些知識(shí)需要知道,在JavaScript中,所有的對(duì)象的基類是Object,基類通過(guò)prototype定義了很多成員和方法,例如toString, toLocaleString, valueOf
這里我以toString()來(lái)做一介紹,請(qǐng)看下面示例:

Js代碼
  1. var obj = { "toString" : function() { return "This is an object."; } };   
  2. alert(obj);  

 

我們注意到當(dāng)alert的時(shí)候,toString()方法被調(diào)用了,事實(shí)上,當(dāng)javascript需要將一個(gè)對(duì)象轉(zhuǎn)換成字符串時(shí)就隱式調(diào)用這個(gè)對(duì)象的toString()方法,例如alert或者document.write或者字符串需要進(jìn)行+運(yùn)算等等。參加下面示例代碼:

Js代碼
  1. Date.prototype.toString = function(){ alert('This is called');}   
  2. var dt= new Date(new Date());   
  3.   
  4. Date.prototype.toString = function(){ alert('This is called');}   
  5. var dt= new Date() + 1;  

 

通過(guò)這個(gè)例子我們驗(yàn)證了這一點(diǎn),即使一個(gè)對(duì)象作為入口參數(shù)也可能會(huì)調(diào)用其toString方法。除了這一點(diǎn)外,該示例同時(shí)演示了如何覆蓋基類中定義的方法。

 

全局變量和局部變量

 

在JavaScript中,在全局上下文中聲明的變量作為全局變量,而在對(duì)象或方法內(nèi)部聲明的對(duì)象則作為本地變量。請(qǐng)參見下面的代碼:

Js代碼
  1. var global = 1;   
  2. function mm()   
  3. {   
  4.     var global = 2; // 聲明本地變量   
  5.     alert(this.global); // 等價(jià)于alert(global);   
  6. }   
  7. mm();   
  8. alert(this.global); // 等價(jià)于alert(global);  

 

上面例子我們可以看出本地變量和全局變量即使同名也不會(huì)出現(xiàn)沖突。
另外Javascript有一個(gè)特性就是變量不用聲明就可以使用,在第一次使用一個(gè)未聲明的變量時(shí),系統(tǒng)會(huì)自動(dòng)聲明該變量,并將其作為全局變量。但是在構(gòu)建大型應(yīng)用程序的時(shí)候,這一點(diǎn)是非常具有破壞性的,如果該變量名在多個(gè)腳本塊中出現(xiàn),引起變量名沖突,導(dǎo)致嚴(yán)重的程序錯(cuò)誤。因此,我們應(yīng)該盡量避免使用全局變量,并且保持先聲明后使用的良好習(xí)慣。

在JavaScript中this關(guān)鍵字是比較重要的一個(gè)特點(diǎn),它會(huì)隨調(diào)用對(duì)象而發(fā)生改變,始終與當(dāng)前對(duì)象的上下文保持一致,這里一個(gè)例子讓我們演示this并且同時(shí)繼續(xù)深入研究toString,首先我們使用構(gòu)造器方式創(chuàng)建一個(gè)對(duì)象,代碼如下:

Js代碼
  1. function obj(params){   
  2. toString = function() { return 'This is an object.'; }   
  3. }    
  4.   
  5. alert(new obj());  

 

你會(huì)發(fā)現(xiàn)當(dāng)運(yùn)行這段代碼的時(shí)候,瀏覽器將會(huì)拋出一個(gè)錯(cuò)誤。
下面我們?cè)倏戳硗鈨啥未a:

Js代碼
  1. function obj(params){   
  2. aMethod = function() { return 'This is global method.'; }   
  3. }    
  4. alert(new obj()); // 正常執(zhí)行   
  5.   
  6.   
  7. function obj(params){   
  8. this.toString = function() { return 'This is local method.'; }   
  9. }    
  10.   
  11. alert(new obj()); // 正常執(zhí)行  

 

第一個(gè)函數(shù)聲明雖沒(méi)有使用this關(guān)鍵字,這時(shí)如果初始化對(duì)象那么將聲明一個(gè)全局方法aMethod。第二個(gè)函數(shù)聲明則為對(duì)象定義了一個(gè)自己的toString()方法。

當(dāng)分析這兩個(gè)函數(shù)的時(shí)候,你會(huì)注意到JavaScript的另一個(gè)特性,解釋執(zhí)行,所以

Js代碼
  1. function obj(params)   
  2. {   
  3.         aMethod = function()   
  4.         {   
  5.                 return 'This is global method.';   
  6.         }   
  7. }   
  8. alert(aMethod()); // 次句會(huì)報(bào)錯(cuò)   
  9.   
  10. function obj(params)   
  11. {   
  12.         aMethod = function()   
  13.         {   
  14.                 return 'This is global method.';   
  15.         }   
  16. }   
  17. new obj(); // 實(shí)例化的時(shí)候,聲明了全局變量阿Method()方法   
  18. alert(aMethod()); // 正常執(zhí)行  

通過(guò)上面的例子我們知道關(guān)鍵字this非常重要,如果使用不當(dāng),可能會(huì)造成全局函數(shù)的改變。有一點(diǎn)需要記住,絕不要調(diào)用包含“this”(卻沒(méi)有所屬對(duì)象)的函數(shù)。否則,將違反全局命名空間,因?yàn)樵谡{(diào)用這樣的函數(shù)時(shí),“this”將引用全局對(duì)象,而這必然會(huì)給您的應(yīng)用程序帶來(lái)災(zāi)難。

如下面的例子,當(dāng)對(duì)象沒(méi)有定義this指定的函數(shù)(isNaN)時(shí),那么可能覆蓋全局的同名函數(shù),看一些代碼示例:

正確使用this的例子:

Js代碼
  1. alert(isNaN(1)); // 全局函數(shù)isNaN   
  2.   
  3. function obj(params)   
  4. {   
  5.         this.toString = function(){return 'This is an object.';};   
  6.         this.isNaN = function()   
  7.         {   
  8.                 return 'not anymore';   
  9.         };   
  10. }   
  11.   
  12. var o = new obj(); // 正確使用方式,調(diào)用構(gòu)造函數(shù)   
  13. alert(o.isNaN(1)); // 此時(shí)obj定義中的this指向o這個(gè)實(shí)例而不是全局上下文   
  14. alert(isNaN(1)); // 全局函數(shù)未發(fā)生變化  

 

錯(cuò)誤的例子:

Js代碼
  1. alert(isNaN(1)); // 全局函數(shù)isNaN   
  2.   
  3. function obj(params)   
  4. {   
  5.         isNaN = function()   
  6.         {   
  7.                 return 'not anymore';   
  8.         }   
  9. }   
  10.   
  11. obj(); // 錯(cuò)誤的使用方式,this指向全局上下文,全局函數(shù)isNaN被覆蓋   
  12. alert(isNaN(1)); // 全局函數(shù)發(fā)生改變  

 

同時(shí)我們還注意到有一些全局函數(shù)則無(wú)法覆蓋,例如toString()

下面我們看JavaScript的一個(gè)很好用的方法:call

 

關(guān)于call的解釋:

call方法可以用來(lái)代替另一個(gè)對(duì)象調(diào)用一個(gè)方法。call方法可以將一個(gè)函數(shù)的對(duì)象上下文從初始化的上下文改變?yōu)橛蓆hisObj指定的新對(duì)象。

可以這樣來(lái)理解:

我們定義了一個(gè)函數(shù)abc:

Js代碼
  1. function abc()   
  2. {   
  3.         alert(this.member1);   
  4. }   
  5.   
  6. var obj = {member1:"Hello world!",show:abc};   
  7. var obj2 = {member1:"Hello world again!",show:abc};   
  8.   
  9. obj.show();   
  10.   
  11. // 也可以使用   
  12. abc.call(obj);   
  13. abc.call(obj2);  

 

修改后的另一個(gè)版本:

Js代碼
  1. member1 = 'test';   
  2.   
  3. function abc()   
  4. {   
  5.         alert(this.member1);   
  6. }   
  7.   
  8. var obj = { member1:"Hello world", show:abc};   
  9. var obj2 = { member1:"Hello world again", show:abc};   
  10.   
  11. obj.show();   
  12.   
  13. // 也可以使用   
  14. abc.call(obj);   
  15. abc.call(obj2);   
  16.   
  17. abc(); // 此時(shí)abc中的this指向了當(dāng)前上下文  

 

每個(gè)函數(shù)都有call方法,上面的過(guò)程中我們看到用另一個(gè)對(duì)象代替調(diào)用顯示方法,并且注意到this在對(duì)象上下文中的改變。

通過(guò)上面基礎(chǔ)知識(shí)的研究,讓我們?cè)傧蚯翱绯鲆徊?,使?strong>call的特性來(lái)實(shí)現(xiàn)類的繼承,參見下面的示例:

Js代碼
  1. // 統(tǒng)一類構(gòu)造器   
  2. function MyClassInitor()   
  3. {   
  4.         this.base();   
  5.         if(!this.mm)   
  6.         {   
  7.                 alert('未定義成員函數(shù):mm()');   
  8.         }   
  9.   
  10.         return this;   
  11. }   
  12.   
  13. // 定義一個(gè)基類   
  14. function baseClass()   
  15. {   
  16.         if(!this.tt) // 判斷該成員是否被繼承類覆蓋   
  17.      {   
  18.                 this.tt = '基類成員';   
  19.         }   
  20. }   
  21.   
  22. // 從基類繼承   
  23. var obj = { member1:"Hello world", base:baseClass, gg:function(){ alert('I am an GG');}};   
  24.   
  25. var obj2 = { member1:"Hello world again", base:baseClass,mm:function(name){alert('I am MM '+name + '.');}, tt:"覆蓋基類的tt成員"};   
  26.   
  27. var o = MyClassInitor.call(obj);   
  28. var o2 = MyClassInitor.call(obj2);   
  29.   
  30. alert(o.tt);   
  31. alert(o2.tt);   
  32.   
  33. o2.mm('Mary');  

 

雖然跟高級(jí)編程語(yǔ)言的語(yǔ)法有點(diǎn)不同,但是你必須了解JavaScript的語(yǔ)法特點(diǎn)。通過(guò)這個(gè)例子,我們什么分析了thiscall的配合,但是實(shí)際進(jìn)行類繼承設(shè)計(jì)時(shí)往往不會(huì)采用此方法進(jìn)行實(shí)現(xiàn),后面我們介紹Prototype時(shí)再做詳細(xì)介紹。

 

命名空間

前面我們了解完類、對(duì)象的聲明,下面看一下Javascript中命名空間的處理,大家知道,在高級(jí)編程語(yǔ)言中我們非常熟練的使用命名空間來(lái)避免變量或方法名的沖突,那么同樣我們也可以在JavaScript中使用命名空間來(lái)為我們的類和方法進(jìn)行界定。在JavaScript中命名空間的聲明與其它高級(jí)語(yǔ)言略有不同,下面是一個(gè)命名空間聲明的示例:

Js代碼
  1. var System = {};   
  2. var System.Web = {};  

 

通過(guò)這兩行代碼我們就有了System和System.Web兩個(gè)命名空間,回想一下前面我們介紹的知識(shí),你很快可以發(fā)現(xiàn),這是兩個(gè)對(duì)象聲明語(yǔ)句。在JavaScript中,我們正是使用對(duì)象來(lái)表示命名空間的。但是你必須清楚一點(diǎn),由于JavaScript的特性,在實(shí)際應(yīng)用中,我們不能這么簡(jiǎn)單的來(lái)處理命名空間,因?yàn)槁暶髡Z(yǔ)句可能同時(shí)出現(xiàn)在多個(gè)地方或者多個(gè)js文件中,我們知道,在JavaScript中,最后聲明的變量會(huì)覆蓋前面同名的變量,因此通常我們要加一些判斷代碼來(lái)防止重復(fù)聲明,例如:

Js代碼
  1. if(typeof System == 'undefined'var System = {};  

 

這樣即使這段代碼在程序中重復(fù)出現(xiàn)多次我們也可以保證System對(duì)象只聲明一次。關(guān)于這一點(diǎn),大家如果深入研究過(guò)AjaxPro和其它很多大型JavaScript框架,會(huì)發(fā)現(xiàn)當(dāng)配合后端應(yīng)用程序的時(shí)候,它是多么的有用。例如AjaxPro的類型注冊(cè),關(guān)于AjaxPro可參見我另一篇文章《AjaxPro框架剖析》。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服