淺談Javascript面向?qū)ο缶幊?/h1>
更新時(shí)間:2011年11月15日 01:34:01 作者:
Javascript是一門很靈活的語(yǔ)言,允許我們模擬面向?qū)ο缶幊讨械暮芏鄼C(jī)機(jī)制
在JS中充分使用面向?qū)ο笤O(shè)計(jì)思想,可以極大限度的提升代碼重用、降低模塊間的偶合、更好的邏輯分層與并行開發(fā)。下面分幾個(gè)步驟簡(jiǎn)單談下我的理解。
一、數(shù)據(jù)類型與包裝類
包裝類 …… 類型名 …… 常見(jiàn)值 …… 分類
Number …… number …… 123.123 …… 基本數(shù)據(jù)類型
Boolean …… Boolean …… true、false …… 基本數(shù)據(jù)類型
String …… string …… “hello world!” …… 基本數(shù)據(jù)類型
Object …… object …… {}、[] …… 復(fù)合數(shù)據(jù)類型
Function …… function …… function(){} …… 特殊類型
無(wú) …… undefined …… undefined、未定義 …… 小數(shù)據(jù)類型
無(wú) …… null …… null …… 小數(shù)據(jù)類型
內(nèi)置類型與本文關(guān)系不大,不列出。
二、引用類型與值類型
引用類型:object function
值類型:number、boolean、string、null、undefined
三、new function(構(gòu)造器)與prototype(原型)
關(guān)于prototype的設(shè)計(jì)模式就不多說(shuō)了,網(wǎng)上很多介紹,以一個(gè)例子介紹一下js中使用new構(gòu)造對(duì)象的過(guò)程。
function classname(){this.id=0;} var v=new classname();
當(dāng)使用function構(gòu)造對(duì)象時(shí),進(jìn)行以下流程:
1、 查找classname的prototype,并進(jìn)行淺拷貝。
2、 綁定this指針到拷貝來(lái)的對(duì)象。
3、 將this.constructor屬性設(shè)置為classname。
[注:其實(shí)classname.prototype.constructor的值也被設(shè)置為classname,第六部分會(huì)說(shuō)明]
4、 執(zhí)行用戶{}中的代碼。
5、 返回this指針賦予左值v。
四、實(shí)現(xiàn)面向?qū)ο蟮娜齻€(gè)基本特征
1、 封裝
封裝這個(gè)大家都明白,在js中,重點(diǎn)在于訪問(wèn)權(quán)限。在其他原生支持面向?qū)ο笳Z(yǔ)言中,一般支持public、protected、private三個(gè)關(guān)鍵字來(lái)控制訪問(wèn)權(quán)限,但在js中,我們只能依靠復(fù)雜的作用域關(guān)系來(lái)控制:
復(fù)制代碼 代碼如下:
function classname(a){
var uid=a; //uin為模擬private,作用域?yàn)閧},外部無(wú)法使用
this.getuid=function(){return a;} //為uid提供一個(gè)外部只讀接口 obj.getuid();
this.setuid=function(val){a=val} //為uid提供一個(gè)外部可寫接口obj.setuid(5);
this.id=uid; //id為模擬public obj.id 使用
}
classname.prototype.func=function(){}; //模擬public方法 obj.func()調(diào)用
classname.stafunc=function(){}; //模擬靜態(tài)方法 classname.stafunc()調(diào)用
var obj=new classname(1);
[!]非常需要注意的就是,因?yàn)閒unction是引用類型, classname.prototype.func是所有對(duì)象共享的一個(gè)function對(duì)象(每個(gè)對(duì)象僅存著引用),因此對(duì)象規(guī)模不大。而使用this.getuid和this.setuid為定義一個(gè)function,因此每個(gè)對(duì)象實(shí)例都會(huì)存一份,如果放肆使用這種方法,會(huì)造成對(duì)象規(guī)模龐大,影響性能。個(gè)人認(rèn)為模擬private變量的意義不大。
[!]如果有需求真的需要大量使用this.xxx=function(){}這種情況,在function(){}中的this指針與最外的this指針是不同的,最好在類定義的首行加上var _this=this;,這樣在this.xxx=function(){}中也可以方便使用綁定的指針。
2、 繼承
繼承的實(shí)現(xiàn),主要有2種方法:第一種是使用javascript本身的原型模型,通過(guò)給prototype賦值并改變其constructor屬性來(lái)實(shí)現(xiàn)繼承;第二種方法是不使用prototype,手動(dòng)實(shí)現(xiàn)將父對(duì)象的所有屬性方法深拷貝到子對(duì)象。比如A需要繼承B,第一種寫法可以:A.prototype=new B();A.prototype.constructor=A; 第二種寫法可以寫一個(gè)遞歸,或者使用jquery中的方法extend。另外,如果要實(shí)現(xiàn)多繼承的話,prototype就真的好麻煩了(需要依次多個(gè)類,還要建空對(duì)象來(lái)接),第二種方法就比較簡(jiǎn)單,依次拷貝即可。一般這種繼承為了找父類方便,可以在對(duì)象中加個(gè)屬性,引用父類。
3、 多態(tài)
函數(shù)重載就不說(shuō)了,都會(huì),檢查參數(shù)即可,很靈活。隱藏屬性就是直接賦值undefined。需要注意的是,如果是打算繼承B類的prototype,一定要建一個(gè)空對(duì)象來(lái)接,否則的話,你給類寫方法的話,相當(dāng)于直接修改了prototype,就算不寫方法,你最后修改constructor時(shí)也會(huì)造成繼承鏈錯(cuò)亂,接個(gè)空對(duì)象很容易:
復(fù)制代碼 代碼如下:
function temp(){};
temp.prototype=B;
var obj=new temp();
這樣再讓需要繼承B.prototype的類繼承obj即可,即便修改prototype也不會(huì)影響到B。而且也不像繼承new B()那樣浪費(fèi)很多空間。
五、深拷貝與淺拷貝
這個(gè)和其他語(yǔ)言中沒(méi)什么區(qū)別,淺拷貝就是直接拷貝,遇到引用類型或類類型不再深入。深拷貝則是根據(jù)類型判斷,進(jìn)行遞歸拷貝。
六、prototype.constructor
這個(gè)值主要是用于維護(hù)繼承的原型鏈。一篇文章已經(jīng)寫的非常詳細(xì),請(qǐng)參考:http://bbs.51js.com/thread-84148-1-1.html
七、JS的面向?qū)ο箝_發(fā)
由于我不是前臺(tái)開發(fā)人員,見(jiàn)過(guò)項(xiàng)目有限,僅談自己的經(jīng)驗(yàn)。
我開發(fā)過(guò)的B/S,常用兩種架構(gòu),一種是以CGI為主,由后臺(tái)語(yǔ)言去生成HTML,JS僅僅做一些用戶交互,ajax通信等。另外一種是使用MVC,后臺(tái)語(yǔ)言僅僅生成JSON,View層完全由JS組件在客戶端實(shí)現(xiàn)。后者一般大量使用面向?qū)ο蟮乃枷脒M(jìn)行編程,將組件封裝成類,將JSON傳入構(gòu)造函數(shù),再由控制器或布局組件Add進(jìn)來(lái)。由于組件可以重用,在開發(fā)后臺(tái)管理系統(tǒng)、JS游戲上,效率還是很可觀的。
您可能感興趣的文章:- 面向?qū)ο蟮腏avascript之二(接口實(shí)現(xiàn)介紹)
- Javascript 面向?qū)ο螅ㄈ┙涌诖a
- JavaScript面向?qū)ο笾薪涌趯?shí)現(xiàn)方法詳解
- Javascript之面向?qū)ο?-接口
- JavaScript接口的實(shí)現(xiàn)三種方式(推薦)
- JavaScript接口實(shí)現(xiàn)代碼 (Interfaces In JavaScript)
- Javascript 面向?qū)ο螅ㄒ唬?共有方法,私有方法,特權(quán)方法)
- js面向?qū)ο笾R?jiàn)創(chuàng)建對(duì)象的幾種方式(工廠模式、構(gòu)造函數(shù)模式、原型模式)
- javascript面向?qū)ο笕腴T基礎(chǔ)詳細(xì)介紹
- 從面試題學(xué)習(xí)Javascript 面向?qū)ο螅▌?chuàng)建對(duì)象)
- Javascript 面向?qū)ο螅ǘ┓庋b代碼
- JavaScript 接口原理與用法實(shí)例詳解
相關(guān)文章
-
JavaScript 對(duì)象鏈?zhǔn)讲僮鳒y(cè)試代碼
自從使用了jQuery以后,對(duì)它的鏈?zhǔn)讲僮骱苁且蕾?,以至于常常覺(jué)得其他庫(kù)不好用。。
2010-04-04
-
關(guān)于javascript function對(duì)象那些迷惑分析
關(guān)于javascript function對(duì)象那些迷惑分析,學(xué)習(xí)js面向?qū)ο蟮呐笥芽梢詤⒖枷隆?/div> 2011-10-10
-
DOMAssitant最新版 DOMAssistant 2.5發(fā)布
google code上的project ,值得大家學(xué)習(xí)它的類庫(kù) 2007-12-12
-
JavaScript中使用構(gòu)造函數(shù)實(shí)現(xiàn)繼承的代碼
JavaScript中借用構(gòu)造函數(shù)實(shí)現(xiàn)繼承的代碼,需要的朋友可以參考下。 2010-08-08
-
JavaScript 工具庫(kù) Cloudgamer JavaScript Library v0.1 發(fā)布
研究了一年多的js,也差不多寫一個(gè)自己的js庫(kù)了。
我寫這個(gè)不算框架,只是一個(gè)小型的js工具庫(kù),所以我用的名字是Library。
2009-10-10
-
JavaScript面向?qū)ο?極簡(jiǎn)主義法minimalist approach)
荷蘭程序員 Gabor de Mooij 提出了一種比 Object.create ()更好的新方法,他稱這種方法為極簡(jiǎn)主義法(minimalist approach)。這也是我推薦的方法 2012-07-07
最新評(píng)論
一、數(shù)據(jù)類型與包裝類
包裝類 …… 類型名 …… 常見(jiàn)值 …… 分類
Number …… number …… 123.123 …… 基本數(shù)據(jù)類型
Boolean …… Boolean …… true、false …… 基本數(shù)據(jù)類型
String …… string …… “hello world!” …… 基本數(shù)據(jù)類型
Object …… object …… {}、[] …… 復(fù)合數(shù)據(jù)類型
Function …… function …… function(){} …… 特殊類型
無(wú) …… undefined …… undefined、未定義 …… 小數(shù)據(jù)類型
無(wú) …… null …… null …… 小數(shù)據(jù)類型
內(nèi)置類型與本文關(guān)系不大,不列出。
二、引用類型與值類型
引用類型:object function
值類型:number、boolean、string、null、undefined
三、new function(構(gòu)造器)與prototype(原型)
關(guān)于prototype的設(shè)計(jì)模式就不多說(shuō)了,網(wǎng)上很多介紹,以一個(gè)例子介紹一下js中使用new構(gòu)造對(duì)象的過(guò)程。
function classname(){this.id=0;} var v=new classname();
當(dāng)使用function構(gòu)造對(duì)象時(shí),進(jìn)行以下流程:
1、 查找classname的prototype,并進(jìn)行淺拷貝。
2、 綁定this指針到拷貝來(lái)的對(duì)象。
3、 將this.constructor屬性設(shè)置為classname。
[注:其實(shí)classname.prototype.constructor的值也被設(shè)置為classname,第六部分會(huì)說(shuō)明]
4、 執(zhí)行用戶{}中的代碼。
5、 返回this指針賦予左值v。
四、實(shí)現(xiàn)面向?qū)ο蟮娜齻€(gè)基本特征
1、 封裝
封裝這個(gè)大家都明白,在js中,重點(diǎn)在于訪問(wèn)權(quán)限。在其他原生支持面向?qū)ο笳Z(yǔ)言中,一般支持public、protected、private三個(gè)關(guān)鍵字來(lái)控制訪問(wèn)權(quán)限,但在js中,我們只能依靠復(fù)雜的作用域關(guān)系來(lái)控制:
復(fù)制代碼 代碼如下:
function classname(a){
var uid=a; //uin為模擬private,作用域?yàn)閧},外部無(wú)法使用
this.getuid=function(){return a;} //為uid提供一個(gè)外部只讀接口 obj.getuid();
this.setuid=function(val){a=val} //為uid提供一個(gè)外部可寫接口obj.setuid(5);
this.id=uid; //id為模擬public obj.id 使用
}
classname.prototype.func=function(){}; //模擬public方法 obj.func()調(diào)用
classname.stafunc=function(){}; //模擬靜態(tài)方法 classname.stafunc()調(diào)用
var obj=new classname(1);
[!]非常需要注意的就是,因?yàn)閒unction是引用類型, classname.prototype.func是所有對(duì)象共享的一個(gè)function對(duì)象(每個(gè)對(duì)象僅存著引用),因此對(duì)象規(guī)模不大。而使用this.getuid和this.setuid為定義一個(gè)function,因此每個(gè)對(duì)象實(shí)例都會(huì)存一份,如果放肆使用這種方法,會(huì)造成對(duì)象規(guī)模龐大,影響性能。個(gè)人認(rèn)為模擬private變量的意義不大。
[!]如果有需求真的需要大量使用this.xxx=function(){}這種情況,在function(){}中的this指針與最外的this指針是不同的,最好在類定義的首行加上var _this=this;,這樣在this.xxx=function(){}中也可以方便使用綁定的指針。
2、 繼承
繼承的實(shí)現(xiàn),主要有2種方法:第一種是使用javascript本身的原型模型,通過(guò)給prototype賦值并改變其constructor屬性來(lái)實(shí)現(xiàn)繼承;第二種方法是不使用prototype,手動(dòng)實(shí)現(xiàn)將父對(duì)象的所有屬性方法深拷貝到子對(duì)象。比如A需要繼承B,第一種寫法可以:A.prototype=new B();A.prototype.constructor=A; 第二種寫法可以寫一個(gè)遞歸,或者使用jquery中的方法extend。另外,如果要實(shí)現(xiàn)多繼承的話,prototype就真的好麻煩了(需要依次多個(gè)類,還要建空對(duì)象來(lái)接),第二種方法就比較簡(jiǎn)單,依次拷貝即可。一般這種繼承為了找父類方便,可以在對(duì)象中加個(gè)屬性,引用父類。
3、 多態(tài)
函數(shù)重載就不說(shuō)了,都會(huì),檢查參數(shù)即可,很靈活。隱藏屬性就是直接賦值undefined。需要注意的是,如果是打算繼承B類的prototype,一定要建一個(gè)空對(duì)象來(lái)接,否則的話,你給類寫方法的話,相當(dāng)于直接修改了prototype,就算不寫方法,你最后修改constructor時(shí)也會(huì)造成繼承鏈錯(cuò)亂,接個(gè)空對(duì)象很容易:
復(fù)制代碼 代碼如下:
function temp(){};
temp.prototype=B;
var obj=new temp();
這樣再讓需要繼承B.prototype的類繼承obj即可,即便修改prototype也不會(huì)影響到B。而且也不像繼承new B()那樣浪費(fèi)很多空間。
五、深拷貝與淺拷貝
這個(gè)和其他語(yǔ)言中沒(méi)什么區(qū)別,淺拷貝就是直接拷貝,遇到引用類型或類類型不再深入。深拷貝則是根據(jù)類型判斷,進(jìn)行遞歸拷貝。
六、prototype.constructor
這個(gè)值主要是用于維護(hù)繼承的原型鏈。一篇文章已經(jīng)寫的非常詳細(xì),請(qǐng)參考:http://bbs.51js.com/thread-84148-1-1.html
七、JS的面向?qū)ο箝_發(fā)
由于我不是前臺(tái)開發(fā)人員,見(jiàn)過(guò)項(xiàng)目有限,僅談自己的經(jīng)驗(yàn)。
我開發(fā)過(guò)的B/S,常用兩種架構(gòu),一種是以CGI為主,由后臺(tái)語(yǔ)言去生成HTML,JS僅僅做一些用戶交互,ajax通信等。另外一種是使用MVC,后臺(tái)語(yǔ)言僅僅生成JSON,View層完全由JS組件在客戶端實(shí)現(xiàn)。后者一般大量使用面向?qū)ο蟮乃枷脒M(jìn)行編程,將組件封裝成類,將JSON傳入構(gòu)造函數(shù),再由控制器或布局組件Add進(jìn)來(lái)。由于組件可以重用,在開發(fā)后臺(tái)管理系統(tǒng)、JS游戲上,效率還是很可觀的。
您可能感興趣的文章:
- 面向?qū)ο蟮腏avascript之二(接口實(shí)現(xiàn)介紹)
- Javascript 面向?qū)ο螅ㄈ┙涌诖a
- JavaScript面向?qū)ο笾薪涌趯?shí)現(xiàn)方法詳解
- Javascript之面向?qū)ο?-接口
- JavaScript接口的實(shí)現(xiàn)三種方式(推薦)
- JavaScript接口實(shí)現(xiàn)代碼 (Interfaces In JavaScript)
- Javascript 面向?qū)ο螅ㄒ唬?共有方法,私有方法,特權(quán)方法)
- js面向?qū)ο笾R?jiàn)創(chuàng)建對(duì)象的幾種方式(工廠模式、構(gòu)造函數(shù)模式、原型模式)
- javascript面向?qū)ο笕腴T基礎(chǔ)詳細(xì)介紹
- 從面試題學(xué)習(xí)Javascript 面向?qū)ο螅▌?chuàng)建對(duì)象)
- Javascript 面向?qū)ο螅ǘ┓庋b代碼
- JavaScript 接口原理與用法實(shí)例詳解
相關(guān)文章
JavaScript 對(duì)象鏈?zhǔn)讲僮鳒y(cè)試代碼
自從使用了jQuery以后,對(duì)它的鏈?zhǔn)讲僮骱苁且蕾?,以至于常常覺(jué)得其他庫(kù)不好用。。2010-04-04關(guān)于javascript function對(duì)象那些迷惑分析
關(guān)于javascript function對(duì)象那些迷惑分析,學(xué)習(xí)js面向?qū)ο蟮呐笥芽梢詤⒖枷隆?/div> 2011-10-10DOMAssitant最新版 DOMAssistant 2.5發(fā)布
google code上的project ,值得大家學(xué)習(xí)它的類庫(kù)2007-12-12JavaScript中使用構(gòu)造函數(shù)實(shí)現(xiàn)繼承的代碼
JavaScript中借用構(gòu)造函數(shù)實(shí)現(xiàn)繼承的代碼,需要的朋友可以參考下。2010-08-08JavaScript 工具庫(kù) Cloudgamer JavaScript Library v0.1 發(fā)布
研究了一年多的js,也差不多寫一個(gè)自己的js庫(kù)了。 我寫這個(gè)不算框架,只是一個(gè)小型的js工具庫(kù),所以我用的名字是Library。2009-10-10JavaScript面向?qū)ο?極簡(jiǎn)主義法minimalist approach)
荷蘭程序員 Gabor de Mooij 提出了一種比 Object.create ()更好的新方法,他稱這種方法為極簡(jiǎn)主義法(minimalist approach)。這也是我推薦的方法2012-07-07最新評(píng)論