Javascript模塊模式分析
更新時(shí)間:2008年05月16日 22:10:54 作者:
javascritp模式講解全局變量是魔鬼。在YUI中,我們僅用兩個(gè)全局變量:YAHOO和YAHOO_config。YUI的一切都是使用YAHOO對(duì)象級(jí)的成員或這個(gè)成員作用域內(nèi)的變量。我們建議在你的應(yīng)用程序也使用類(lèi)似的規(guī)則。
Douglas Crockford已經(jīng)傳授了一個(gè)有用的單例模式(singleton pattern)實(shí)現(xiàn)此規(guī)則,我認(rèn)為他的模式有益于你基于YUI的那些應(yīng)用。Douglas叫它模塊模式(module pattern)。它是如下工作的:
創(chuàng)建一個(gè)命名空間對(duì)象:如果你使用YUI,可以用YAHOO.namespace()方法: YAHOO.namespace("myProject");這分配了一個(gè)空的myProject對(duì)象,是YAHOO的一個(gè)成員(如 果myProject已存在的話(huà),則不會(huì)被覆蓋)?,F(xiàn)在我們可以開(kāi)始添加YAHOO.myProject的成員。
對(duì)你的命名空間對(duì)象分配一個(gè)匿名函數(shù)返回值:
YAHOO.myProject.myModule = function () {
return {
myPublicProperty: "我作為YAHOO.myProject.myModule.myPublicProperty被訪(fǎng)問(wèn)。";
myPublicMethod: function () {
YAHOO.log("我作為YAHOO.myProject.myModule.myPublicMethod被訪(fǎng)問(wèn)。");
}
};
}(); // 這個(gè)括號(hào)導(dǎo)致匿名函數(shù)被執(zhí)行且返回
注意有閉合大括號(hào)和緊接著的括號(hào)()的最后一行—這種符號(hào)導(dǎo)致了匿名函數(shù)的立即執(zhí)行,返回包含myPublicProperty和myPublicMethod的對(duì)象。只要這個(gè)匿名函數(shù)一返回,返回對(duì)象就作為YAHOO.myProject.myModule被訪(fǎng)問(wèn)。
在匿名函數(shù)中,在返回語(yǔ)句前加入“私有”方法和變量。到目前為止,我們只是將myPublicProperty和myPublicMethod直接分配到Y(jié)AHOO.myProject.myModule中。此外,當(dāng)我們?cè)诜祷卣Z(yǔ)句之前放置一些代碼時(shí),這個(gè)模式還支持被增加的效用。
YAHOO.myProject.myModule = function () {
//“私有”變量:
var myPrivateVar = “我僅能在YAHOO.myProject.myModule內(nèi)被訪(fǎng)問(wèn)。”;
//私有方法:
var myPrivateMethod = function () {
YAHOO.log(”我僅能在YAHOO.myProject.myModule內(nèi)被訪(fǎng)問(wèn)?!?;
}
return {
myPublicProperty: “我作為YAHOO.myProject.myModule.myPublicProperty能被訪(fǎng)問(wèn)?!?
myPublicMethod: function () {
YAHOO.log(”我作為YAHOO.myProject.myModule.myPublicMethod能被訪(fǎng)問(wèn)。”);
//在myProject,我能訪(fǎng)問(wèn)私有的變量和方法
YAHOO.log(myPrivateVar);
YAHOO.log(myPrivateMethod());
//myPublicMethod的原生作用域是myProject,我們可以用“this”來(lái)訪(fǎng)問(wèn)公共成員。
YAHOO.log(this.myPublicProperty);
}
};
}();
在上面的代碼中,我們從一個(gè)匿名函數(shù)返回有兩個(gè)成員的一個(gè)對(duì)象。在YAHOO.myProject.myModule內(nèi)部,可以分別用this.myPublicProperty和this.myPublicMethod來(lái)訪(fǎng)問(wèn)。在YAHOO.myProject.myModule外部,公共成員可以用YAHOO.myProject.myModule.myPublicProperty和YAHOO.myProject.myModule.myPublicMethod來(lái)訪(fǎng)問(wèn)。
私有變量myPrivateProperty和myPrivateMethod只能被匿名函數(shù)本身或返回對(duì)象的成員訪(fǎng)問(wèn)。盡管匿名函數(shù)會(huì)立即執(zhí)行和終止,但它們依然是保留著,憑借閉包(closure)的力量——通過(guò)一個(gè)函數(shù)的局部變量在這個(gè)函數(shù)返回后是保留的規(guī)則。只要 YAHOO.myProject.myModule需要它們,我們的兩個(gè)私有變量就不會(huì)被銷(xiāo)毀。
實(shí)踐這個(gè)模式。讓我們來(lái)看看這個(gè)模式的一個(gè)常見(jiàn)應(yīng)用案例。假設(shè)你有一個(gè)列表,列表上的一些項(xiàng)可以被拖拽。應(yīng)用拖拽的項(xiàng)上有拖拽的CSS類(lèi)。
<!--這個(gè)腳本文件包含所有的YUI實(shí)用程序-->
<script type="text/javascript"
src="http://yui.yahooapis.com/2.2.2/build/utilities/utilities.js"></script>
<ul id="myList">
<li class="draggable">一項(xiàng)</li>
<li>二項(xiàng)</li> <!--二項(xiàng)將不能被拖拽-->
<li class="draggable">三項(xiàng)</li>
</ul>
<script>
YAHOO.namespace("myProject");
YAHOO.myProject.myModule = function () {
//YUI實(shí)用程序的私有簡(jiǎn)寫(xiě)引用:
var yue = YAHOO.util.Event,
yud = YAHOO.util.Dom;
//私有方法
var getListItems = function () {
// 注意這個(gè)地方使用其他的私有變量,包括"yud"YAHOO.util.Dom的簡(jiǎn)寫(xiě):
var elList = yud.get("myList");
var aListItems = yud.getElementsByClassName(
"draggable", //得到僅有CSS類(lèi)"draggable"的項(xiàng)
"li", //僅返回列表項(xiàng)
elList //限定搜索改元素的子
);
return aListItems;
};
//這個(gè)放回的對(duì)象將變成YAHOO.myProject.myModule:
return {
aDragObjects: [], //可對(duì)外訪(fǎng)問(wèn)的,存儲(chǔ)DD對(duì)象
init: function () {
//直到DOM完全加載好,才實(shí)現(xiàn)列表項(xiàng)可拖拽:
yue.onDOMReady(this.makeLIsDraggable, this, true);
},
makeLIsDraggable: function () {
var aListItems = getListItems(); //我們可以拖拽的那些元素
for (var i=0, j=aListItems.length; i<j; i++) {
this.aDragObjects.push(new YAHOO.util.DD(aListItems[i]));
}
}
};
}();
//上面的代碼已經(jīng)執(zhí)行,所以我們能立即訪(fǎng)問(wèn)init方法:
YAHOO.myProject.myModule.init();
</script>
這是一個(gè)簡(jiǎn)單的例子,特意寫(xiě)的詳細(xì)一些——如果按照這種方式做,我們無(wú)疑能把它寫(xiě)的更緊湊。當(dāng)項(xiàng)目變得更加復(fù)雜和它的API增加,這個(gè)模式縮放的很好。通過(guò)這種方式,它避免了全局命名空間,提供了對(duì)外的可以訪(fǎng)問(wèn)的API方法,支持受保護(hù)或“私有”的數(shù)據(jù)和方法。
[1]原文:《a javascript module pattern》。這是在YUI blog上的,有的地方可能打不開(kāi),可以搜一下英文的轉(zhuǎn)載或者利用搜索引擎的緩存也能看。
[2]《A JavaScript Module Pattern - JavaScript的一種模組模式》這是別人的翻譯,參考了不少,不過(guò)感覺(jué)挺不方便看的,這是我翻譯的這篇文章的一個(gè)原因,當(dāng)然最主要的原因是這篇文章算是學(xué)習(xí)YUI的最基礎(chǔ)的文章了,整個(gè)YUI的模塊模式都基于此。
創(chuàng)建一個(gè)命名空間對(duì)象:如果你使用YUI,可以用YAHOO.namespace()方法: YAHOO.namespace("myProject");這分配了一個(gè)空的myProject對(duì)象,是YAHOO的一個(gè)成員(如 果myProject已存在的話(huà),則不會(huì)被覆蓋)?,F(xiàn)在我們可以開(kāi)始添加YAHOO.myProject的成員。
對(duì)你的命名空間對(duì)象分配一個(gè)匿名函數(shù)返回值:
YAHOO.myProject.myModule = function () {
return {
myPublicProperty: "我作為YAHOO.myProject.myModule.myPublicProperty被訪(fǎng)問(wèn)。";
myPublicMethod: function () {
YAHOO.log("我作為YAHOO.myProject.myModule.myPublicMethod被訪(fǎng)問(wèn)。");
}
};
}(); // 這個(gè)括號(hào)導(dǎo)致匿名函數(shù)被執(zhí)行且返回
注意有閉合大括號(hào)和緊接著的括號(hào)()的最后一行—這種符號(hào)導(dǎo)致了匿名函數(shù)的立即執(zhí)行,返回包含myPublicProperty和myPublicMethod的對(duì)象。只要這個(gè)匿名函數(shù)一返回,返回對(duì)象就作為YAHOO.myProject.myModule被訪(fǎng)問(wèn)。
在匿名函數(shù)中,在返回語(yǔ)句前加入“私有”方法和變量。到目前為止,我們只是將myPublicProperty和myPublicMethod直接分配到Y(jié)AHOO.myProject.myModule中。此外,當(dāng)我們?cè)诜祷卣Z(yǔ)句之前放置一些代碼時(shí),這個(gè)模式還支持被增加的效用。
YAHOO.myProject.myModule = function () {
//“私有”變量:
var myPrivateVar = “我僅能在YAHOO.myProject.myModule內(nèi)被訪(fǎng)問(wèn)。”;
//私有方法:
var myPrivateMethod = function () {
YAHOO.log(”我僅能在YAHOO.myProject.myModule內(nèi)被訪(fǎng)問(wèn)?!?;
}
return {
myPublicProperty: “我作為YAHOO.myProject.myModule.myPublicProperty能被訪(fǎng)問(wèn)?!?
myPublicMethod: function () {
YAHOO.log(”我作為YAHOO.myProject.myModule.myPublicMethod能被訪(fǎng)問(wèn)。”);
//在myProject,我能訪(fǎng)問(wèn)私有的變量和方法
YAHOO.log(myPrivateVar);
YAHOO.log(myPrivateMethod());
//myPublicMethod的原生作用域是myProject,我們可以用“this”來(lái)訪(fǎng)問(wèn)公共成員。
YAHOO.log(this.myPublicProperty);
}
};
}();
在上面的代碼中,我們從一個(gè)匿名函數(shù)返回有兩個(gè)成員的一個(gè)對(duì)象。在YAHOO.myProject.myModule內(nèi)部,可以分別用this.myPublicProperty和this.myPublicMethod來(lái)訪(fǎng)問(wèn)。在YAHOO.myProject.myModule外部,公共成員可以用YAHOO.myProject.myModule.myPublicProperty和YAHOO.myProject.myModule.myPublicMethod來(lái)訪(fǎng)問(wèn)。
私有變量myPrivateProperty和myPrivateMethod只能被匿名函數(shù)本身或返回對(duì)象的成員訪(fǎng)問(wèn)。盡管匿名函數(shù)會(huì)立即執(zhí)行和終止,但它們依然是保留著,憑借閉包(closure)的力量——通過(guò)一個(gè)函數(shù)的局部變量在這個(gè)函數(shù)返回后是保留的規(guī)則。只要 YAHOO.myProject.myModule需要它們,我們的兩個(gè)私有變量就不會(huì)被銷(xiāo)毀。
實(shí)踐這個(gè)模式。讓我們來(lái)看看這個(gè)模式的一個(gè)常見(jiàn)應(yīng)用案例。假設(shè)你有一個(gè)列表,列表上的一些項(xiàng)可以被拖拽。應(yīng)用拖拽的項(xiàng)上有拖拽的CSS類(lèi)。
<!--這個(gè)腳本文件包含所有的YUI實(shí)用程序-->
<script type="text/javascript"
src="http://yui.yahooapis.com/2.2.2/build/utilities/utilities.js"></script>
<ul id="myList">
<li class="draggable">一項(xiàng)</li>
<li>二項(xiàng)</li> <!--二項(xiàng)將不能被拖拽-->
<li class="draggable">三項(xiàng)</li>
</ul>
<script>
YAHOO.namespace("myProject");
YAHOO.myProject.myModule = function () {
//YUI實(shí)用程序的私有簡(jiǎn)寫(xiě)引用:
var yue = YAHOO.util.Event,
yud = YAHOO.util.Dom;
//私有方法
var getListItems = function () {
// 注意這個(gè)地方使用其他的私有變量,包括"yud"YAHOO.util.Dom的簡(jiǎn)寫(xiě):
var elList = yud.get("myList");
var aListItems = yud.getElementsByClassName(
"draggable", //得到僅有CSS類(lèi)"draggable"的項(xiàng)
"li", //僅返回列表項(xiàng)
elList //限定搜索改元素的子
);
return aListItems;
};
//這個(gè)放回的對(duì)象將變成YAHOO.myProject.myModule:
return {
aDragObjects: [], //可對(duì)外訪(fǎng)問(wèn)的,存儲(chǔ)DD對(duì)象
init: function () {
//直到DOM完全加載好,才實(shí)現(xiàn)列表項(xiàng)可拖拽:
yue.onDOMReady(this.makeLIsDraggable, this, true);
},
makeLIsDraggable: function () {
var aListItems = getListItems(); //我們可以拖拽的那些元素
for (var i=0, j=aListItems.length; i<j; i++) {
this.aDragObjects.push(new YAHOO.util.DD(aListItems[i]));
}
}
};
}();
//上面的代碼已經(jīng)執(zhí)行,所以我們能立即訪(fǎng)問(wèn)init方法:
YAHOO.myProject.myModule.init();
</script>
這是一個(gè)簡(jiǎn)單的例子,特意寫(xiě)的詳細(xì)一些——如果按照這種方式做,我們無(wú)疑能把它寫(xiě)的更緊湊。當(dāng)項(xiàng)目變得更加復(fù)雜和它的API增加,這個(gè)模式縮放的很好。通過(guò)這種方式,它避免了全局命名空間,提供了對(duì)外的可以訪(fǎng)問(wèn)的API方法,支持受保護(hù)或“私有”的數(shù)據(jù)和方法。
[1]原文:《a javascript module pattern》。這是在YUI blog上的,有的地方可能打不開(kāi),可以搜一下英文的轉(zhuǎn)載或者利用搜索引擎的緩存也能看。
[2]《A JavaScript Module Pattern - JavaScript的一種模組模式》這是別人的翻譯,參考了不少,不過(guò)感覺(jué)挺不方便看的,這是我翻譯的這篇文章的一個(gè)原因,當(dāng)然最主要的原因是這篇文章算是學(xué)習(xí)YUI的最基礎(chǔ)的文章了,整個(gè)YUI的模塊模式都基于此。
您可能感興趣的文章:
- JavaScript模塊管理的簡(jiǎn)單實(shí)現(xiàn)方式詳解
- 關(guān)于Javascript模塊化和命名空間管理的問(wèn)題說(shuō)明
- javascript模塊化是什么及其優(yōu)缺點(diǎn)介紹
- Javascript模塊化編程詳解
- Javascript模塊化編程(三)require.js的用法及功能介紹
- 詳解JavaScript模塊化開(kāi)發(fā)
- Javascript模塊化編程(一)AMD規(guī)范(規(guī)范使用模塊)
- JavaScript模塊化之使用requireJS按需加載
- javascript 模塊依賴(lài)管理的本質(zhì)深入詳解
相關(guān)文章
layuiAdmin循環(huán)遍歷展示商品圖片列表的方法
今天小編就為大家分享一篇layuiAdmin循環(huán)遍歷展示商品圖片列表的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09關(guān)于 byval 與 byref 的區(qū)別分析總結(jié)
關(guān)于 byval 與 byref 的區(qū)別分析總結(jié)...2007-10-10JavaScript字符串操作的四個(gè)實(shí)用技巧
在制作前端頁(yè)面的過(guò)程中,經(jīng)常需要用到JavaScript進(jìn)行邏輯處理,很多時(shí)候都需要對(duì)字符串進(jìn)行操作,這篇文章主要給大家介紹了關(guān)于JavaScript字符串操作的四個(gè)實(shí)用技巧,需要的朋友可以參考下2021-07-07JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)電子時(shí)鐘
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)電子時(shí)鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06Javascript表單特效之十大常用原理性樣例代碼大總結(jié)
開(kāi)頭說(shuō)這個(gè)常用原理性樣例,大家可能不太清楚,這篇文章主要是針對(duì)實(shí)際開(kāi)發(fā)中常用的一些代碼分析,主要是針對(duì)表單處理方法的一些資料,推薦大家收藏2016-07-07自己寫(xiě)的Javascript計(jì)算時(shí)間差函數(shù)
Javascript計(jì)算時(shí)間差函數(shù),獲得時(shí)間差,時(shí)間格式為 年-月-日 小時(shí):分鐘:秒 或者 年/月/日 小時(shí):分鐘:秒。2013-10-10js快速與任意QQ號(hào)碼建立臨時(shí)對(duì)話(huà)
那時(shí)候在群里討論的,吸納很多人的方法與意見(jiàn),修改而成的2008-10-10