方案的話其實(shí)有特別多的,就看你自己的思維構(gòu)造,然后想做一個(gè)什么方法的,也想做一個(gè)什么顏色字體等等。
公司主營(yíng)業(yè)務(wù):成都網(wǎng)站制作、網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。成都創(chuàng)新互聯(lián)公司推出汾西免費(fèi)做網(wǎng)站回饋大家。
基礎(chǔ)
我們首先簡(jiǎn)單地概述一下,自從三年前Eric Miraglia(YUI的開(kāi)發(fā)者)第一次發(fā)表博客描述模塊化模式以來(lái)的一些模塊化模式。如果你已經(jīng)對(duì)于這些模塊化模式非常熟悉了,大可以直接跳過(guò)本節(jié),從“進(jìn)階模式”開(kāi)始閱讀。
匿名閉包
這是一種讓一切變?yōu)榭赡艿幕窘Y(jié)構(gòu),同時(shí)它也是Javascript最棒的特性。我們將簡(jiǎn)單地創(chuàng)建一個(gè)匿名函數(shù)并立即執(zhí)行它。所有的代碼將跑在這個(gè)函數(shù)內(nèi),生存在一個(gè)提供私有化的閉包中,它足以使得這些閉包中的變量能夠貫穿我們的應(yīng)用的整個(gè)生命周期。
復(fù)制代碼 代碼如下:
(function () {
// ... all vars and functions are in this scope only
// still maintains access to all globals
}());
注意這對(duì)包裹匿名函數(shù)的最外層括號(hào)。因?yàn)镴avascript的語(yǔ)言特性,這對(duì)括號(hào)是必須的。在js中由關(guān)鍵詞function開(kāi)頭的語(yǔ)句總是會(huì)被認(rèn)為是函數(shù)聲明式。把這段代碼包裹在括號(hào)中就可以讓解釋器知道這是個(gè)函數(shù)表達(dá)式。
全局變量導(dǎo)入
Javascript有一個(gè)特性叫做隱式全局變量。無(wú)論一個(gè)變量名在哪兒被用到了,解釋器會(huì)根據(jù)作用域鏈來(lái)反向找到這個(gè)變量的var聲明語(yǔ)句。如果沒(méi)有找到var聲明語(yǔ)句,那么這個(gè)變量就會(huì)被視為全局變量。如果這個(gè)變量用在一句賦值語(yǔ)句中,同時(shí)這個(gè)變量又不存在時(shí),就會(huì)創(chuàng)建出一個(gè)全局變量。這意味著在匿名閉包中使用或創(chuàng)建全局變量是很容易的。不幸的是,這會(huì)導(dǎo)致寫(xiě)出的代碼極難維護(hù),因?yàn)閷?duì)于人的直觀感受來(lái)說(shuō),一眼根本分不清那些是全局的變量。
幸運(yùn)的是,我們的匿名函數(shù)提供了簡(jiǎn)單的變通方法。只要將全局變量作為參數(shù)傳遞到我們的匿名函數(shù)中,就可以得到比隱式全局變量更清晰又快速的代碼了。下面是示例:
復(fù)制代碼 代碼如下:
(function ($, YAHOO) {
// now have access to globals jQuery (as $) and YAHOO in this code
}(jQuery, YAHOO));
模塊導(dǎo)出
有時(shí)你不僅想要使用全局變量,你還想要聲明它們,以供反復(fù)使用。我們可以很容易地通過(guò)導(dǎo)出它們來(lái)做到這一點(diǎn)——通過(guò)匿名函數(shù)的返回值。這樣做將會(huì)完成一個(gè)基本的模塊化模式雛形,接下來(lái)會(huì)是一個(gè)完整的例子:
復(fù)制代碼 代碼如下:
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
注意我們已經(jīng)聲明了一個(gè)叫做MODULE的全局模塊,它擁有2個(gè)公有的屬性:一個(gè)叫做MODULE.moduleMethod的方法和一個(gè)叫做MODULE.moduleProperty的變量。另外,它還維護(hù)了一個(gè)利用匿名函數(shù)閉包的、私有的內(nèi)置狀態(tài)。同時(shí),我們可以很容易地導(dǎo)入需要的全局變量,并像之前我們所學(xué)到的那樣來(lái)使用這個(gè)模塊化模式。
進(jìn)階模式
上面一節(jié)所描述的基礎(chǔ)已經(jīng)足以應(yīng)對(duì)許多情況,現(xiàn)在我們可以將這個(gè)模塊化模式進(jìn)一步的發(fā)展,創(chuàng)建更多強(qiáng)大的、可擴(kuò)展的結(jié)構(gòu)。讓我們從MODULE模塊開(kāi)始,一一介紹這些進(jìn)階模式。
放大模式
整個(gè)模塊必須在一個(gè)文件中是模塊化模式的一個(gè)限制。任何一個(gè)參與大型項(xiàng)目的人都會(huì)明白將js拆分多個(gè)文件的價(jià)值。幸運(yùn)的是,我們擁有一個(gè)很棒的實(shí)現(xiàn)來(lái)放大模塊。首先,我們導(dǎo)入一個(gè)模塊,并為它添加屬性,最后再導(dǎo)出它。下面是一個(gè)例子——從原本的MODULE中放大它:
復(fù)制代碼 代碼如下:
var MODULE = (function (my) {
my.anotherMethod = function () {
// added method...
};
return my;
}(MODULE));
我們用var關(guān)鍵詞來(lái)保證一致性,雖然它在此處不是必須的。在這段代碼執(zhí)行完之后,我們的模塊就已經(jīng)擁有了一個(gè)新的、叫做MODULE.anotherMethod的公有方法。這個(gè)放大文件也會(huì)維護(hù)它自己的私有內(nèi)置狀態(tài)和導(dǎo)入的對(duì)象。
寬放大模式
我們的上面例子需要我們的初始化模塊最先被執(zhí)行,然后放大模塊才能執(zhí)行,當(dāng)然有時(shí)這可能也不一定是必需的。Javascript應(yīng)用可以做到的、用來(lái)提升性能的、最棒的事之一就是異步執(zhí)行腳本。我們可以創(chuàng)建靈活的多部分模塊并通過(guò)寬放大模式使它們可以以任意順序加載。每一個(gè)文件都需要按下面的結(jié)構(gòu)組織:
復(fù)制代碼 代碼如下:
var MODULE = (function (my) {
// add capabilities...
return my;
}(MODULE || {}));
在這個(gè)模式中,var表達(dá)式使必需的。注意如果MODULE還未初始化過(guò),這句導(dǎo)入語(yǔ)句會(huì)創(chuàng)建MODULE。這意味著你可以用一個(gè)像LABjs的工具來(lái)并行加載你所有的模塊文件,而不會(huì)被阻塞。
緊放大模式
寬放大模式非常不錯(cuò),但它也會(huì)給你的模塊帶來(lái)一些限制。最重要的是,你不能安全地覆蓋模塊的屬性。你也無(wú)法在初始化的時(shí)候,使用其他文件中的屬性(但你可以在運(yùn)行的時(shí)候用)。緊放大模式包含了一個(gè)加載的順序序列,并且允許覆蓋屬性。這兒是一個(gè)簡(jiǎn)單的例子(放大我們的原始MODULE):
復(fù)制代碼 代碼如下:
var MODULE = (function (my) {
var old_moduleMethod = my.moduleMethod;
my.moduleMethod = function () {
// method override, has access to old through old_moduleMethod...
};
return my;
}(MODULE));
我們?cè)谏厦娴睦又懈采w了MODULE.moduleMethod的實(shí)現(xiàn),但在需要的時(shí)候,可以維護(hù)一個(gè)對(duì)原來(lái)方法的引用。
克隆與繼承
復(fù)制代碼 代碼如下:
var MODULE_TWO = (function (old) {
var my = {},
key;
for (key in old) {
if (old.hasOwnProperty(key)) {
my[key] = old[key];
}
}
var super_moduleMethod = old.moduleMethod;
my.moduleMethod = function () {
// override method on the clone, access to super through super_moduleMethod
};
return my;
}(MODULE));
這個(gè)模式可能是最缺乏靈活性的一種選擇了。它確實(shí)使得代碼顯得很整潔,但那是用靈活性的代價(jià)換來(lái)的。正如我上面寫(xiě)的這段代碼,如果某個(gè)屬性是對(duì)象或者函數(shù),它將不會(huì)被復(fù)制,而是會(huì)成為這個(gè)對(duì)象或函數(shù)的第二個(gè)引用。修改了其中的某一個(gè)就會(huì)同時(shí)修改另一個(gè)(譯者注:因?yàn)樗鼈兏揪褪且粋€(gè)啊?。_@可以通過(guò)遞歸克隆過(guò)程來(lái)解決這個(gè)對(duì)象克隆問(wèn)題,但函數(shù)克隆可能無(wú)法解決,也許用eval可以解決吧。因此,我在這篇文章中講述這個(gè)方法僅僅是考慮到文章的完整性。
跨文件私有變量
把一個(gè)模塊分到多個(gè)文件中有一個(gè)重大的限制:每一個(gè)文件都維護(hù)了各自的私有變量,并且無(wú)法訪問(wèn)到其他文件的私有變量。但這個(gè)問(wèn)題是可以解決的。這里有一個(gè)維護(hù)跨文件私有變量的、寬放大模塊的例子:
復(fù)制代碼 代碼如下:
var MODULE = (function (my) {
var _private = my._private = my._private || {},
_seal = my._seal = my._seal || function () {
delete my._private;
delete my._seal;
delete my._unseal;
},
_unseal = my._unseal = my._unseal || function () {
my._private = _private;
my._seal = _seal;
my._unseal = _unseal;
};
// permanent access to _private, _seal, and _unseal
return my;
}(MODULE || {}));
所有文件可以在它們各自的_private變量上設(shè)置屬性,并且它理解可以被其他文件訪問(wèn)。一旦這個(gè)模塊加載完成,應(yīng)用程序可以調(diào)用MODULE._seal()來(lái)防止外部對(duì)內(nèi)部_private的調(diào)用。如果這個(gè)模塊需要被重新放大,在任何一個(gè)文件中的內(nèi)部方法可以在加載新的文件前調(diào)用_unseal(),并在新文件執(zhí)行好以后再次調(diào)用_seal()。我如今在工作中使用這種模式,而且我在其他地方還沒(méi)有見(jiàn)過(guò)這種方法。我覺(jué)得這是一種非常有用的模式,很值得就這個(gè)模式本身寫(xiě)一篇文章。
子模塊
我們的最后一種進(jìn)階模式是顯而易見(jiàn)最簡(jiǎn)單的。創(chuàng)建子模塊有許多優(yōu)秀的實(shí)例。這就像是創(chuàng)建一般的模塊一樣:
復(fù)制代碼 代碼如下:
MODULE.sub = (function () {
var my = {};
// ...
return my;
}());
雖然這看上去很簡(jiǎn)單,但我覺(jué)得還是值得在這里提一提。子模塊擁有一切一般模塊的進(jìn)階優(yōu)勢(shì),包括了放大模式和私有化狀態(tài)。
如今backbone、emberjs、spinejs、batmanjs
等MVC框架侵襲而來(lái)。CommonJS、AMD、NodeJS、RequireJS、SeaJS、curljs等模塊化的JavaScript撲面而
來(lái)。web前端已經(jīng)演變成大前端,web前端的發(fā)展速度之快。
1)我們來(lái)看看什么是模塊化?
模塊化是一種將系統(tǒng)分離成獨(dú)立功能部分的方法,可將系統(tǒng)分割成獨(dú)立的功能部分,嚴(yán)格定義模塊接口、模塊間具有透明性。javascript中的模塊在一些C、PHP、java中比較常見(jiàn):
c中使用include 包含.h文件;php中使用require_once包含.php文件
java使用import導(dǎo)入包
此中都有模塊化的思想。
2)模塊化的優(yōu)缺點(diǎn):
a優(yōu)點(diǎn):
可維護(hù)性
1.靈活架構(gòu),焦點(diǎn)分離
2.方便模塊間組合、分解
3.方便單個(gè)模塊功能調(diào)試、升級(jí)
4.多人協(xié)作互不干擾
可測(cè)試性
1.可分單元測(cè)試
b缺點(diǎn):
性能損耗
1.系統(tǒng)分層,調(diào)用鏈會(huì)很長(zhǎng)
2.模塊間通信,模塊間發(fā)送消息會(huì)很耗性能
3)最近的項(xiàng)目中也有用到模塊化,
使用的是seajs,但是當(dāng)引用到j(luò)query,jquery easyui/或者jquery
UI組件時(shí),有可能會(huì)用到很多jquery插件,那這樣要是實(shí)現(xiàn)一個(gè)很復(fù)雜的交互時(shí),模塊間的依賴會(huì)很多,使用define()方法引入模塊會(huì)很多,不知
有么有什么好的方法?
4)附:
內(nèi)聚度
內(nèi)聚度指模塊內(nèi)部實(shí)現(xiàn),它是信息隱藏和局部化概念的自然擴(kuò)展,它標(biāo)志著一個(gè)模塊內(nèi)部各成分彼此結(jié)合的緊密程度。好處也很明顯,當(dāng)把相關(guān)的任務(wù)分組后去閱讀就容易多了。 設(shè)計(jì)時(shí)應(yīng)該盡可能的提高模塊內(nèi)聚度,從而獲得較高的模塊獨(dú)立性。
耦合度
耦合度則是指模塊之間的關(guān)聯(lián)程度的度量。耦合度取決于模塊之間接口的復(fù)雜性,進(jìn)入或調(diào)用模塊的位置等。與內(nèi)聚度相反,在設(shè)計(jì)時(shí)應(yīng)盡量追求松散耦合的系統(tǒng)。
模塊模式被定義為給類提供私有和公共封裝的一種方法,也就是我們常說(shuō)的“模塊化”。簡(jiǎn)單示例代碼:var Module = (function (w) { var my={}, privateVar = 8;//私有屬性 function privateFun() {//私有方法 return ++privateVar; }; my.publicVar = 1;//公共屬性 my.moduleFun = function () {//公共方法 return privateFun(); }; return my; })(window);
可維護(hù)性
靈活架構(gòu),焦點(diǎn)分離
方便模塊間組合、分解
方便單個(gè)模塊功能調(diào)試、升級(jí)
多人協(xié)作互不干擾
可測(cè)試性,可分單元測(cè)試;
性能損耗
系統(tǒng)分層,調(diào)用鏈會(huì)很長(zhǎng)
模塊間通信,模塊間發(fā)送消息會(huì)很耗性能
最近的項(xiàng)目中也有用到模塊化;
使用的是seajs,但是當(dāng)引用到j(luò)query,jquery easyui/或者jquery;
UI組件時(shí),有可能會(huì)用到很多jquery插件,那這樣要是實(shí)現(xiàn)一個(gè)很復(fù)雜的交互時(shí),模塊間的依賴會(huì)很多,使用define()方法引入模塊會(huì)很多。
EMCAScript6(ES6)是最新的Javascript,它包含了一些很棒的新特性。這些特性擁有不同程度的復(fù)雜性,對(duì)于簡(jiǎn)單的腳本和復(fù)雜的應(yīng)用程序都非常的有用。\x0d\x0a\x0d\x0a增加的新特性:\x0d\x0a\x0d\x0a1.箭頭操作符\x0d\x0a 如果你會(huì)C#或者Java,你肯定知道lambda表達(dá)式,ES6中新增的箭頭操作符=便有異曲同工之妙。它簡(jiǎn)化了函數(shù)的書(shū)寫(xiě)。操作符左邊為輸入的參數(shù),而右邊則是進(jìn)行的操作以及返回的值Inputs=outputs。\x0d\x0a 我們知道在JS中回調(diào)是經(jīng)常的事,而一般回調(diào)又以匿名函數(shù)的形式出現(xiàn),每次都需要寫(xiě)一個(gè)function,甚是繁瑣。當(dāng)引入箭頭操作符后可以方便地寫(xiě)回調(diào)了。\x0d\x0a\x0d\x0a2.類的支持\x0d\x0a ES6中添加了對(duì)類的支持,引入了class關(guān)鍵字(其實(shí)class在JavaScript中一直是保留字,目的就是考慮到可能在以后的新版本中會(huì)用到,現(xiàn)在終于派上用場(chǎng)了)。JS本身就是面向?qū)ο蟮?,ES6中提供的類實(shí)際上只是JS原型模式的包裝?,F(xiàn)在提供原生的class支持后,對(duì)象的創(chuàng)建,繼承更加直觀了,并且父類方法的調(diào)用,實(shí)例化,靜態(tài)方法和構(gòu)造函數(shù)等概念都更加形象化。\x0d\x0a\x0d\x0a3.增強(qiáng)的對(duì)象字面量\x0d\x0a 對(duì)象字面量被增強(qiáng)了,寫(xiě)法更加簡(jiǎn)潔與靈活,同時(shí)在定義對(duì)象的時(shí)候能夠做的事情更多了。具體表現(xiàn)在:\x0d\x0a(1).可以在對(duì)象字面量里面定義原型\x0d\x0a(2).定義方法可以不用function關(guān)鍵字\x0d\x0a(3).直接調(diào)用父類方法\x0d\x0a\x0d\x0a4.字符串模板\x0d\x0a 字符串模板相對(duì)簡(jiǎn)單易懂些。ES6中允許使用反引號(hào) ` 來(lái)創(chuàng)建字符串,此種方法創(chuàng)建的字符串里面可以包含由美元符號(hào)加花括號(hào)包裹的變量${vraible}。如果你使用過(guò)像C#等后端強(qiáng)類型語(yǔ)言的話,對(duì)此功能應(yīng)該不會(huì)陌生。\x0d\x0a\x0d\x0a5.解構(gòu)\x0d\x0a 自動(dòng)解析數(shù)組或?qū)ο笾械闹怠1热缛粢粋€(gè)函數(shù)要返回多個(gè)值,常規(guī)的做法是返回一個(gè)對(duì)象,將每個(gè)值做為這個(gè)對(duì)象的屬性返回。但在ES6中,利用解構(gòu)這一特性,可以直接返回一個(gè)數(shù)組,然后數(shù)組中的值會(huì)自動(dòng)被解析到對(duì)應(yīng)接收該值的變量中。\x0d\x0a\x0d\x0a6.參數(shù)默認(rèn)值,不定參數(shù),拓展參數(shù)\x0d\x0a(1).默認(rèn)參數(shù)值\x0d\x0a 現(xiàn)在可以在定義函數(shù)的時(shí)候指定參數(shù)的默認(rèn)值了,而不用像以前那樣通過(guò)邏輯或操作符來(lái)達(dá)到目的了。\x0d\x0a(2).不定參數(shù)\x0d\x0a 不定參數(shù)是在函數(shù)中使用命名參數(shù)同時(shí)接收不定數(shù)量的未命名參數(shù)。這只是一種語(yǔ)法糖,在以前的JavaScript代碼中我們可以通過(guò)arguments變量來(lái)達(dá)到這一目的。不定參數(shù)的格式是三個(gè)句點(diǎn)后跟代表所有不定參數(shù)的變量名。比如下面這個(gè)例子中,?x代表了所有傳入add函數(shù)的參數(shù).\x0d\x0a(3).拓展參數(shù)\x0d\x0a 拓展參數(shù)則是另一種形式的語(yǔ)法糖,它允許傳遞數(shù)組或者類數(shù)組直接做為函數(shù)的參數(shù)而不用通過(guò)apply。\x0d\x0a\x0d\x0a6.let與const 關(guān)鍵字\x0d\x0a 可以把let看成var,只是它定義的變量被限定在了特定范圍內(nèi)才能使用,而離開(kāi)這個(gè)范圍則無(wú)效。const則很直觀,用來(lái)定義常量,即無(wú)法被更改值的變量。\x0d\x0a\x0d\x0a7.for of 值遍歷\x0d\x0a 我們都知道for in 循環(huán)用于遍歷數(shù)組,類數(shù)組或?qū)ο螅珽S6中新引入的for of循環(huán)功能相似,不同的是每次循環(huán)它提供的不是序號(hào)而是值。\x0d\x0a8.模塊\x0d\x0a 在ES6標(biāo)準(zhǔn)中,JavaScript原生支持module了。這種將JS代碼分割成不同功能的小塊進(jìn)行模塊化的概念是在一些三方規(guī)范中流行起來(lái)的,比如CommonJS和AMD模式。\x0d\x0a\x0d\x0a9.Map,Set 和 WeakMap,WeakSet\x0d\x0a 這些是新加的集合類型,提供了更加方便的獲取屬性值的方法,不用像以前一樣用hasOwnProperty來(lái)檢查某個(gè)屬性是屬于原型鏈上的呢還是當(dāng)前對(duì)象的。同時(shí),在進(jìn)行屬性值添加與獲取時(shí)有專門的get,set方法。\x0d\x0a\x0d\x0a10.Proxies\x0d\x0a Proxy可以監(jiān)聽(tīng)對(duì)象身上發(fā)生了什么事情,并在這些事情發(fā)生后執(zhí)行一些相應(yīng)的操作。一下子讓我們對(duì)一個(gè)對(duì)象有了很強(qiáng)的追蹤能力,同時(shí)在數(shù)據(jù)綁定方面也很有用處。\x0d\x0a\x0d\x0a11.Symbols\x0d\x0a 我們知道對(duì)象其實(shí)是鍵值對(duì)的集合,而鍵通常來(lái)說(shuō)是字符串。而現(xiàn)在除了字符串外,我們還可以用symbol這種值來(lái)做為對(duì)象的鍵。Symbol是一種基本類型,像數(shù)字,字符串還有布爾一樣,它不是一個(gè)對(duì)象。Symbol 通過(guò)調(diào)用symbol函數(shù)產(chǎn)生,它接收一個(gè)可選的名字參數(shù),該函數(shù)返回的symbol是唯一的。之后就可以用這個(gè)返回值做為對(duì)象的鍵了。Symbol還可以用來(lái)創(chuàng)建私有屬性,外部無(wú)法直接訪問(wèn)由symbol做為鍵的屬性值。\x0d\x0a\x0d\x0a12.Math,Number,String,Object 的新API\x0d\x0a 對(duì)Math,Number,String還有Object等添加了許多新的API。下面代碼同樣來(lái)自es6features,對(duì)這些新API進(jìn)行了簡(jiǎn)單展示。\x0d\x0a\x0d\x0a13.Promises\x0d\x0a Promises是處理異步操作的一種模式,之前在很多三方庫(kù)中有實(shí)現(xiàn),比如jQuery的deferred 對(duì)象。當(dāng)你發(fā)起一個(gè)異步請(qǐng)求,并綁定了.when(), .done()等事件處理程序時(shí),其實(shí)就是在應(yīng)用promise模式。
文章題目:模塊JavaScript,模塊JavaScript
網(wǎng)站鏈接:http://jinyejixie.com/article10/dsdigdo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號(hào)、移動(dòng)網(wǎng)站建設(shè)、電子商務(wù)、品牌網(wǎng)站制作、網(wǎng)站內(nèi)鏈、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)