JavaScript 面向?qū)ο笕腴T精簡篇第1/2頁
封裝 :javascript中創(chuàng)建對象的模式中,個人認(rèn)為通過閉包才算的上是真正意義上的封裝 ,所以首先我們先來簡單介紹一下閉包,看下面這個例子:
<script type="text/javascript">
function myInfo(){
var name ="老魚",age =27;
var myInfo = "my name is" + name + "i am" + age +"years old";
function showInfo(){
alert(myInfo);
}
return showInfo;
}
var oldFish = myInfo();
oldFish();
</script>
是不是很眼熟呢?沒錯了,這其實(shí)就是一個簡單的閉包應(yīng)用了。簡單解釋一下:上面的函數(shù)myInfo中定義的變量,在它的內(nèi)嵌函數(shù)showInfo中是可訪問的(這個很好理解),但是當(dāng)我們把這個內(nèi)嵌函數(shù)的返回引用賦值給一個變量oldFish,這個時候函數(shù)showInfo是在myInfo函數(shù)體外被調(diào)用,但是同樣可以訪問到定義在函數(shù)體內(nèi)的變量。oh yeah!
總結(jié)一下閉包的原理吧:函數(shù)是運(yùn)行在定義他們的作用域中而不是調(diào)用他們的作用域中。 其實(shí)返回一個內(nèi)嵌函數(shù)也是創(chuàng)建閉包最常用的一種方法!
如果覺得上面的解釋太抽象的話,那么我們一起重塑上面的函數(shù),看看這樣是否層次鮮明一些:
<script type="text/javascript">
var ioldFish = function(name,age){
var name = name,age = age;
var myInfo = "my name is" + name + "i am" + age +"years old";
return{
showInfo:function(){
alert(myInfo);
}
}
}
ioldFish("老魚",27).showInfo();
</script>
上例中的編碼風(fēng)格是ext yui 中比較常見的,公私分明,一目了然。通過閉包,我們可以很方便的把一些不希望被外部直接訪問到的東西隱藏起來,你要訪問函數(shù)內(nèi)定義的變量,只能通過特定的方法才可以訪問的到,直接從外部訪問是訪問不到的,寫的挺累,饒了一圈終于轉(zhuǎn)回來了,封裝嘛,不就是把不希望被別人看到的東西隱藏起來嘛!哈哈……
上例如果轉(zhuǎn)換成JQ 的風(fēng)格的話,應(yīng)該如下例所寫,這樣的封裝模式屬于門戶大開型模式,里面定義的變量是可以被外部訪問到的(下面的例子如果你先實(shí)例化一個對象,然后在函數(shù)外部訪問對象的name或者 age屬性都是可以讀取到的)當(dāng)然這種模式下我們可以設(shè)置一些”潛規(guī)則”,讓團(tuán)隊(duì)開發(fā)成員明白哪些變量是私用的,通常我們?nèi)藶榈脑谒接凶兞亢头椒ㄇ凹酉聞澗€”_”,標(biāo)識警戒訊號!從而實(shí)現(xiàn)”封裝”!
<script type="text/javascript">
var ioldFish = function(name,age){
return ioldFish.func.init(name,age);
};
ioldFish.func = ioldFish.prototype ={
init:function(name,age){
this.name = name;
this.age = age;
return this;
},
showInfo:function(){
var info = "my name is" + this.name +"i am " +this.age+"years old";
alert(info);
}
};
ioldFish.func.init.prototype = ioldFish.func;
ioldFish(" 老 魚",27).showInfo();
//var oldFish = new ioldFish("老魚",27);
//alert(oldFish.name);
</script>
可能有人會問,哪種模式好呢?這個怎么說呢?兩種方式都有優(yōu)缺點(diǎn),結(jié)合著用唄!總之一個原則,一定一定不能直接被外部對象訪問的東西,就用閉包封裝吧。”一定一定”四個字很深奧,不斷實(shí)踐中才能體會真諦!
繼承 :提到這個的時候,要順便再補(bǔ)充一句:閉包封裝中的一個缺點(diǎn),不利于子類的派生,所以閉包有風(fēng)險(xiǎn),封裝需謹(jǐn)慎!直觀起見,下面例子中創(chuàng)建對象的方式,采用”門戶大開型”模式。
在javascript中繼承 一般分為三種方式:”類式繼承”,”原型繼承”,”摻元類”。下面簡單的介紹一下三類繼承方式的原理。
A.類式繼承: 這個是現(xiàn)在主流框架中常用的繼承方式,看下例:
<script type="text/javascript">
var Name = function(name){
this.name = name;
};
Name.prototype.getName = function(){
alert(this.name);
};
var Fish = function(name,age){
Name.call(this,name);
this.age = age;
};
Fish.prototype = new Name();
Fish.prototype.constructor = Fish;
Fish.prototype.showInfo = function(){
alert(this.age);
}
var ioldFish = new Fish("老魚",27);
ioldFish.getName();
</script>
上述子類Fish中并沒定義getName方法,但是子類Fish的實(shí)例對象ioldFish依然調(diào)用到了該方法,這是因?yàn)樽宇怓ish繼承了超類 Name中定義的getName方法。解釋一下,這里子類Fish的prototype指到了超類的一個實(shí)例,在子類Fish中雖然沒有申明 getName方法,但是根據(jù)原型鏈原理,會向prototype指向的上一級對象中去查找是否有該方法,如果沒找到該方法,會一直搜索到最初的原型對象。這其實(shí)也就是繼承的原理了。這里特別說明一下,F(xiàn)ish.prototype.constructor = Fish;這句,由于默認(rèn)子類的prototype應(yīng)該是指向本身的,但是之前把prototype指向到了超類的實(shí)例對象,所以在這里要把它設(shè)置回來。當(dāng)然這里可以把相關(guān)代碼通過一個函數(shù)來組織起來,起到偽裝extend的作用
B.原型繼承 ,從內(nèi)存性能上看優(yōu)于類式繼承。
<script type="text/javascript">
function clone(object){
var F = function(){};
F.prototype = object;
return new F();
};
var Name = {
name:"who's name",
showInfo:function(){
alert(this.name);
}
};
var Fish = clone(Name);
//Fish.name = "老魚";
Fish.showInfo();
lt;/script>
很明顯,原型繼承核心就是這個clone函數(shù),同樣是原型鏈的原理,不同的是它直接克隆超類,這樣的話子類就繼承了超類的所有屬性和方法.特別說一下,這類繼承并不需要創(chuàng)建構(gòu)造函數(shù),只需要創(chuàng)建一個對象字變量,定義相應(yīng)的屬性和方法,然后在子類中只需要通過圓點(diǎn)”.”符號來引用屬性和方法就可以了.
相關(guān)文章
Javascript面向?qū)ο笤O(shè)計(jì)一 工廠模式
工廠模式抽象了創(chuàng)建具體對象的過程,但是在ECMAScript中無法創(chuàng)建類,所以就使用一種函數(shù)來封裝以特定接口創(chuàng)建對象的細(xì)節(jié)2011-12-12
new fun的執(zhí)行過程分析,學(xué)習(xí)面向?qū)ο蟮呐笥芽梢詤⒖枷隆?/div> 2010-08-08
javascript 面向?qū)ο笕吕砭氈當(dāng)?shù)據(jù)的封裝
JavaScript 是一種非常靈活的面向?qū)ο蟪绦蛟O(shè)計(jì)語言,它與傳統(tǒng)的強(qiáng)類型的面向?qū)ο蟪绦蛟O(shè)計(jì)語言(如 C++,Java,C# 等)有很大不同,所以要實(shí)現(xiàn)如 C++、java、C# 當(dāng)中的一些特性就需要換一種思考方式來解決。2009-12-12
javascript面向?qū)ο蟮姆绞綄?shí)現(xiàn)的彈出層效果代碼
由于本人以前是.net程序員,所以即使現(xiàn)在在做前端,也習(xí)慣于用面向?qū)ο蟮姆绞骄帉慾s腳本,我想如果你以前也是或者現(xiàn)在還是名第三代程序員的話,應(yīng)該對此并不陌生。2010-01-01
編寫可維護(hù)面向?qū)ο蟮腏avaScript代碼[翻譯]
編寫可維護(hù)面向?qū)ο蟮腏avaScript代碼[翻譯],學(xué)習(xí)js面向?qū)ο缶帉懙呐笥芽梢詤⒖枷隆?/div> 2011-02-02最新評論
大家感興趣的內(nèi)容
最近更新的內(nèi)容
- javascript 對象定義方法 簡單易學(xué)
- Javascript 面向?qū)ο螅ǘ┓庋b代碼
- javascript面向?qū)ο缶幊?一) 實(shí)例代碼
- javascript 面向?qū)ο缶幊? function是方法(函數(shù))
- JavaScript中使用構(gòu)造函數(shù)實(shí)現(xiàn)繼承的代碼
- JavaScript面向?qū)ο蟪绦蛟O(shè)計(jì)三 原型模式(上)
- 面向?qū)ο蟮腏avascript之一(初識Javascript)
- Javascript 面向?qū)ο螅ㄒ唬?共有方法,私有方法,特權(quán)方法)
- javascript 類定義的4種方法
- JavaScript面向?qū)ο?極簡主義法minimalist approac

