日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
JavaScript組件模式深入淺出

“組件模式”是一種很常用的Javascript編碼模式。雖然已經(jīng)被廣泛的應(yīng)用,但是還有一些高級(jí)的用途沒有被關(guān)注。在這邊文章里,我將針對(duì)幾個(gè)比較特別的話題進(jìn)行簡(jiǎn)單的闡述,其中的一些我認(rèn)為應(yīng)該是***次被提及。

成都創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括浦江網(wǎng)站建設(shè)、浦江網(wǎng)站制作、浦江網(wǎng)頁制作以及浦江網(wǎng)絡(luò)營(yíng)銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,浦江網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到浦江省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

基礎(chǔ)

我們從一個(gè)簡(jiǎn)單的組件模式開始說起,這個(gè)模式現(xiàn)在已經(jīng)非常流行,最初是3年前由雅虎YUI的Eric Miraglia在其博客中提出的。如果你已經(jīng)對(duì)這個(gè)模式很熟悉了,那么可以直接跳到“高級(jí)模式”一節(jié)。

匿名閉包(Anonymous Closures)

這是使得模式可以正常工作的語言基礎(chǔ),也實(shí)在是javascript最為實(shí)用的特性之一。我們可以簡(jiǎn)單的創(chuàng)建一個(gè)匿名函數(shù),并且立刻執(zhí)行它。所有運(yùn)行在該函數(shù)里的代碼叫做一個(gè)閉包,它提供了在整個(gè)應(yīng)用程序生命周期中都有效的數(shù)據(jù)隱私控制以及狀態(tài)保存功能。

 
 
 
  1. (function () {        
  2. // ... all vars and functions are in this scope only          
  3. // still maintains access to all globals  
  4. }()); 

請(qǐng)注意()包圍了匿名函數(shù),這是語法的需要,因?yàn)橐詅unction開頭的語句會(huì)被編譯器認(rèn)為的函數(shù)的定義,而加上()就變?yōu)榱藙?chuàng)建了一個(gè)函數(shù)表達(dá)式。

全局導(dǎo)入(Global Import)

JavaScript 有一個(gè)大家熟知的特性叫做implied globals,就是當(dāng)使用一個(gè)變量的時(shí)候,解釋器會(huì)沿著作用域鏈一直向上查找這個(gè)變量的定義,如果沒找到,這個(gè)變量就會(huì)自動(dòng)成為一個(gè)全局(global)變量。這意味著在一個(gè)匿名閉包里去創(chuàng)建一個(gè)全局變量變得非常簡(jiǎn)單。

但是,這產(chǎn)生了很難管理的代碼問題,因?yàn)槲覀儫o法明顯的知道一個(gè)給定的文件里究竟哪些變量是全局的

(譯者注:如果允許這么隱晦的寫法來創(chuàng)建全局變量,則代碼中使用的變量,很難知道是全局的還是局部的。)

幸運(yùn)的是,我們的匿名函數(shù)提供了一個(gè)很簡(jiǎn)單的修改來解決這個(gè)問題。我們傳入一個(gè)全局對(duì)象作為匿名函數(shù)的參數(shù),我們利用這個(gè)參數(shù)導(dǎo)入我們的變量到全局對(duì)象中,這樣做比隱式的聲明全局變量要干凈和快速的多。下面是一個(gè)例子

 
 
 
  1. (function ($, YAHOO) {          
  2. // now have access to globals jQuery (as $) and YAHOO in this code  
  3. }(jQuery, YAHOO)); 

模塊導(dǎo)出(Module Export)

有時(shí)候我們不只是想定義一個(gè)模塊,還想直接使用它,我們可以使用匿名函數(shù)的返回值來實(shí)現(xiàn)。如果這么做,就是實(shí)現(xiàn)了一個(gè)基本的“組件模式”,看下面的例子:

 
 
 
  1. var MODULE = (function () {          
  2. var my = {},privateVariable = 1;                 
  3.  function privateMethod() {                  
  4. // ...          
  5. }  
  6. my.moduleProperty = 1;         
  7.  my.moduleMethod = function () {                  
  8. // ...          
  9. };                  
  10. return my;  
  11. }()); 

要注意的是我們定義了一個(gè)全局組件名字叫“MODULE”,他有兩個(gè)屬性:一個(gè)方法MODULE.moduleMethod以及一個(gè)屬性MODULE.moduleProperty。并且,它通過匿名函數(shù)所在的閉包維護(hù)了一組私有的內(nèi)部狀態(tài)

(譯者注:privateVariable變量和privateMethod方法都是私有的,外部無法訪問)。

這樣的話,我們就可以用上面的模式簡(jiǎn)單的導(dǎo)入需要的全局變量。

高級(jí)模式(Advanced Patterns)

上面的模式已經(jīng)可以解決應(yīng)用中的許多問題,但是我們還可以在這個(gè)基礎(chǔ)上擴(kuò)展出很多強(qiáng)大的,易擴(kuò)展的結(jié)構(gòu)。讓我們一個(gè)個(gè)看一下,繼續(xù)用我們的組件“MODULE”做例子

增益模式(Augmentation)

使用上面的模式的缺點(diǎn)和限制之一,就是整個(gè)模塊必須在一個(gè)文件里。任何在大型項(xiàng)目中工作的人都會(huì)意識(shí)到能將代碼拆分成多個(gè)文件帶來的價(jià)值。幸運(yùn)的是,我們有一個(gè)不錯(cuò)的解決方案叫做“增益組件”。首先,我們導(dǎo)入組件,然后添加屬性,然后再將其導(dǎo)出。下面是一個(gè)例子,為我們的MODULE組件添加增益特性:

 
 
 
  1. var MODULE = (function (my) {          
  2. my.anotherMethod = function () {                  
  3. // added method...          
  4. };          
  5. return my;  
  6. }(MODULE)); 

我們使用var關(guān)鍵字來保持一致性(盡管這不是必須的)。這段代碼執(zhí)行過后,我們的組件就增加了一個(gè)公開的方法叫做MODULE.anotherMethod。這個(gè)增加的文件也會(huì)同時(shí)保持它自己的私有狀態(tài)。

(譯者注:通過增益模式,一個(gè)雷被切分成獨(dú)立的文件,每個(gè)文件關(guān)注它內(nèi)部需要的方法和屬性,并且當(dāng)所有文件合并執(zhí)行后,可以成為一個(gè)完整的組件)

松耦合增益(Loose Augmentation)

我們上面的例子有一個(gè)缺點(diǎn),就是需要MODULE模塊先被創(chuàng)建,然后再執(zhí)行子文件中的增益。這是一種緊耦合的做法。javascript性能優(yōu)化中通常的做法是腳本的異步加載,這樣我們就可以創(chuàng)建由多個(gè)文件組成的易擴(kuò)展的組件,并且他們可以以任何順序來加載,這叫做松耦合增益模式:

 
 
 
  1. var MODULE = (function (my) {          
  2. // add capabilities...                 
  3.  return my;  
  4. }(MODULE || {})); 

在這個(gè)模式中,var關(guān)鍵字是必須的。注意我們的import點(diǎn)(參數(shù))會(huì)自動(dòng)判斷組件是否存在,否則就創(chuàng)建一個(gè)空組件。這意味著你可以使用一些異步加載工具比如LABjs來并行加載你所有的js組件,而不需要block頁面。

緊耦合增益(Tight Augmentation)

“松耦合增益”模式非常棒,不過它也有一些限制,最重要的一個(gè)就是無法重寫屬性。你也無法在初始化組件的時(shí)候使用其他文件的內(nèi)容(因?yàn)榧虞d順序無法保證),“緊耦合增益模式”需要一個(gè)有序的加載順序,但是允許你重寫其他文件的內(nèi)容,這是一個(gè)簡(jiǎn)單的例子:

 
 
 
  1. var MODULE = (function (my) {          
  2. var old_moduleMethod = my.moduleMethod;                  
  3. my.moduleMethod = function () {                  
  4. // method override, has access to old through old_moduleMethod...         
  5.  };                 
  6.  return my;  
  7. }(MODULE)); 

這里我們重寫了 MODULE.moduleMethod,同時(shí)也保存了舊的 MODULE.moduleMethod方法的引用(如果需要的話)

克隆和繼承(Cloning and Inheritance)

 
 
 
  1. var MODULE_TWO = (function (old) {          
  2. var my = {}, key;                  
  3. for (key in old) {                  
  4. if (old.hasOwnProperty(key)) {                          
  5. my[key] = old[key];                  
  6. }          
  7. }                  
  8. var super_moduleMethod = old.moduleMethod;          
  9. my.moduleMethod = function () {                  
  10. // override method on the clone, access to super through super_moduleMethod        };                  
  11. return my;  
  12. }(MODULE)); 

這種模式也許是最沒有擴(kuò)展性的選項(xiàng)了。它雖然看上去讓代碼更簡(jiǎn)潔,但是帶來的是擴(kuò)展性的損失。我們上面的代碼中,所有的屬性和方法都不是副本,他們以“一個(gè)對(duì)象2個(gè)引用”的方式存在。修改其中一個(gè)都會(huì)影響到另外一個(gè)。

跨文件私有狀態(tài)(Cross-File Private State)

將組件分割到多個(gè)文件中的另外一個(gè)限制,就是每個(gè)文件只能訪問他自己的私有狀態(tài),而沒有權(quán)限訪問其他文件的私有數(shù)據(jù)。這個(gè)問題可以解決,下面是一個(gè)“松耦合增益模式”的跨文件訪問私有狀態(tài)的版本:

 
 
 
  1. var MODULE = (function (my) {          
  2. var _private = my._private = my._private || {},                  
  3. _seal = my._seal = my._seal || function () {                          
  4. delete my._private;                          
  5. delete my._seal;                          
  6. delete my._unseal;                  
  7. },                  
  8. _unseal = my._unseal = my._unseal || function () {                          
  9. my._private = _private;                         
  10.  my._seal = _seal;                          
  11. my._unseal = _unseal;                 
  12.  };                  
  13. // permanent access to _private, _seal, and _unseal                  
  14. return my;  
  15. }(MODULE || {})); 

現(xiàn)在任何文件都可以在本地變量_private中設(shè)置屬性,并且會(huì)立即將設(shè)置結(jié)果反饋給其他文件。一旦組件加載完成,應(yīng)用程序應(yīng)該調(diào)用 MODULE._seal()方法,這個(gè)方法會(huì)阻止外部程序訪問內(nèi)部屬性_private。如果這個(gè)組件被其他文件進(jìn)行了擴(kuò)展(增益),則可在加載新的文件之前,調(diào)用_unseal()方法解封,然后在文件加載完之后調(diào)用_seal()再次將類對(duì)外部屏蔽。

(譯者注:注意_unseal方法會(huì)在對(duì)象里添加1個(gè)公開的屬性和2個(gè)公開方法,其他文件就可以在my對(duì)象中隊(duì)private屬性進(jìn)行擴(kuò)展,然后利用_seal()方法刪除公開的屬性,保持對(duì)象的密封性)

這個(gè)模式是今天我在工作的時(shí)候想到的,我沒有在其他地方見過這種用法,我認(rèn)為這是一種十分有用的模式。

子模塊(Sub-modules)

Our final advanced pattern is actually the simplest. There are many good cases for creating sub-modules. It is just like creating regular modules:

我們***的一個(gè)高級(jí)模式實(shí)際上是最簡(jiǎn)單的,創(chuàng)建子模塊有很多的好處,創(chuàng)建子模塊就和創(chuàng)建普通模塊一樣:

 
 
 
  1. MODULE.sub = (function () {          
  2. var my = {};         
  3.  // ...                  
  4. return my;  
  5. }()); 

雖然這很簡(jiǎn)單,但我還是認(rèn)為子模塊應(yīng)該包含進(jìn)來,因?yàn)樽幽K擁有所有正常模塊有的高級(jí)特性,包括增益和私有數(shù)據(jù)保存。

結(jié)論

大多數(shù)高級(jí)模式都可以結(jié)合起來使用,如果是我的話,我比較喜歡把“松耦合增益”、“私有狀態(tài)保存”、“子模式”結(jié)合起來使用

我這篇文字并沒有討論性能相關(guān)的內(nèi)容,不過我想簡(jiǎn)單的說一下:組件模式是對(duì)性能有好處的。因?yàn)樗_實(shí)讓下載快了很多:使用“松耦合增益”模式可以讓腳本并行的無阻塞加載,這加快了下載速度。整體初始化完成的時(shí)間也許比其他方法慢了一些,不過這是值得的。

作為結(jié)尾,這里有一個(gè)子模塊的例子,他動(dòng)態(tài)的加載自己到它的父模塊中。這個(gè)模式允許整個(gè)模塊并行的加載自己,以及自己的子模塊。

譯文出自:刺客之家的博客


網(wǎng)頁名稱:JavaScript組件模式深入淺出
網(wǎng)址分享:http://m.5511xx.com/article/ccchjip.html