自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

模塊化你的JS代碼

開發(fā) 前端
因?yàn)樵谌肿饔糜蛑新暶鞯淖兞亢秃瘮?shù)都自動(dòng)成為全局對(duì)象Window的屬性,這經(jīng)常會(huì)導(dǎo)致命名沖突,還會(huì)導(dǎo)致一些非常重要的可維護(hù)性難題,全局變量越多,引入錯(cuò)誤BUG的概率就越大!所以我們應(yīng)當(dāng)盡可能少地使用全局變量,模塊化的目的之一就是為了解決該問題的!

[[172869]]

為什么要使用模塊模式?

因?yàn)樵谌肿饔糜蛑新暶鞯淖兞亢秃瘮?shù)都自動(dòng)成為全局對(duì)象Window的屬性,這經(jīng)常會(huì)導(dǎo)致命名沖突,還會(huì)導(dǎo)致一些非常重要的可維護(hù)性難題,全局變量越多,引入錯(cuò)誤BUG的概率就越大!所以我們應(yīng)當(dāng)盡可能少地使用全局變量,模塊化的目的之一就是為了解決該問題的!

零全局變量模式

該模式應(yīng)用場(chǎng)景較少,通過一個(gè)IIFE(立即執(zhí)行的匿名函數(shù)),將所有代碼包裝起來,這樣一來所有的變量、函數(shù)都被隱藏在該函數(shù)內(nèi)部,不會(huì)污染全局。

使用情景:

  1. 當(dāng)該代碼不會(huì)被其它代碼所依賴時(shí);
  2. 當(dāng)不需要在運(yùn)行時(shí)不斷的擴(kuò)展或修改該代碼時(shí);
  3. 當(dāng)代碼較短,且無需和其它代碼產(chǎn)生交互時(shí);

單全局變量模式

基本定義

單全局變量模式即只創(chuàng)建一個(gè)全局變量(或盡可能少地創(chuàng)建全局變量),且該全局變量的名稱必須是獨(dú)一無二的,不會(huì)和現(xiàn)在、將來的內(nèi)置API產(chǎn)生沖突,將所有的功能代碼都掛載到這個(gè)全局變量上。

它已經(jīng)被廣泛應(yīng)用于各種流行的類庫中,如:

  1. YUI定義了唯一的YUI全局對(duì)象
  2. JQuery定義了兩個(gè)全局對(duì)象,$和JQuery
  3. Dojo定義了一個(gè)dojo全局對(duì)象
  4. Closure定義了一個(gè)goog全局對(duì)象

例子:

  1. var Mymodule= {}; 
  2.  
  3. Mymodule.Book = function(){...}; 
  4. Mymodule.Book.prototype.getName = function(){....}; 
  5.  
  6. Mymodule.Car = function(){...}; 
  7. Mymodule.Car.prototype.getWheels = function(){....};  

一個(gè)模塊的定義

模塊是一種通用的功能片段,它并沒有創(chuàng)建新的全局變量或命名空間,相反,所有的代碼都存放于一個(gè)單函數(shù)中,可以用一個(gè)名稱來表示這個(gè)模塊,同樣這個(gè)模塊可以依賴其他模塊。

  1. function CoolModule(){ 
  2.         var something = 'cool'
  3.         var another = [1,2,3]; 
  4.         function doSomething(){ 
  5.             console.log( something); 
  6.         } 
  7.         function doAnother(){ 
  8.             console.log(another.join('!')); 
  9.         } 
  10.         return { 
  11.             doSomething: doSomething, 
  12.             doAnother: doAnother 
  13.         }; 
  14. var foo = CoolModule(); 
  15. foo.doSomething(); //cool 
  16. foo.doAnother(); //1!2!3  

這里的CoolModule 就是一個(gè)模塊,不過它只是一個(gè)函數(shù),這里調(diào)用CoolModule函數(shù)來創(chuàng)建一個(gè)模塊的實(shí)例foo,此時(shí)就形成了閉包(因?yàn)镃oolModule返回一個(gè)對(duì)象,其中的一個(gè)屬性引用了內(nèi)部函數(shù)),模塊CoolModule返回的對(duì)象就是該模塊的公共API(也可以直接返回一個(gè)內(nèi)部函數(shù))

所以,模塊模式需要具備兩個(gè)必要條件:

  1. 必須有外部的封閉函數(shù),且該函數(shù)必須至少被調(diào)用一次(每次調(diào)用都會(huì)創(chuàng)建一個(gè)新的模塊實(shí)例),如CoolModule
  2. 封閉函數(shù)必須至少有一個(gè)內(nèi)部函數(shù)被返回,這樣內(nèi)部函數(shù)才能在私有作用域中形成閉包,并且可以訪問或修改私有的狀態(tài)

單例模塊模式的實(shí)現(xiàn):

  1. var foo = ( function CoolModule(){ 
  2.         ...//代碼同上例 
  3. })(); 
  4. foo.doSomething(); 
  5. foo.doAnother();  

還可以通過在模塊內(nèi)部保留對(duì)公共API對(duì)象的內(nèi)部引用,這樣就可以在內(nèi)部對(duì)模塊實(shí)例進(jìn)行修改,包括添加、刪除方法和屬性

  1. function CoolModule(){ 
  2.     var something = 'cool'
  3.     var another = [1,2,3]; 
  4.     function change() { 
  5.         pubicAPI.doSomething = doAnother; 
  6.     } 
  7.     function doSomething(){ 
  8.         console.log( something); 
  9.     } 
  10.     function doAnother(){ 
  11.         console.log(another.join('!')); 
  12.     } 
  13.     var pubicAPI = { 
  14.         change: change, 
  15.         doSomething: doSomething 
  16.     }; 
  17.     return pubicAPI; 
  18. var foo = CoolModule(); 
  19. foo.doSomething(); //cool 
  20. foo.change(); 
  21. foo.doSomething(); //1!2!3 
  22. var foo1 = CoolModule(); 
  23. foo1.doSomething(); //cool  

現(xiàn)代的模塊機(jī)制

命名空間是簡單的通過在全局變量中添加屬性來表示的功能性分組。

將不同功能按照命名空間進(jìn)行分組,可以讓你的單全局變量變得井然有序,同時(shí)可以讓團(tuán)隊(duì)成員能夠知曉新功能應(yīng)該在哪個(gè)部分中定義,或者去哪個(gè)部分查找已有功能。

例如:定義一個(gè)全局變量Y,Y.DOM下的所有方法都是和操作DOM相關(guān)的,Y.Event下的所有方法都是和事件相關(guān)的。

  1. 常見的用法是為每一個(gè)單獨(dú)的JS文件創(chuàng)建一個(gè)新的全局變量來聲明自己的命名空間;
  2. 每個(gè)文件都需要給一個(gè)命名空間掛載功能;這時(shí)就需要首先保證該命名空間是已經(jīng)存在的,可以在單全局變量中定義一個(gè)方法來處理該任務(wù):該方法在創(chuàng)建新的命名空間時(shí)不會(huì)對(duì)已有的命名空間造成破壞,使用命名空間時(shí)也不需要再去判斷它是否存在。
  1. var MyGolbal = { 
  2.     namespace: function (ns) { 
  3.         var parts = ns.split('.'), 
  4.             obj = this, 
  5.             i, len = parts.length; 
  6.         for(i=0;i<len;i++){ 
  7.             if(!obj[parts[i]]){ 
  8.                 obj[parts[i]] = {} 
  9.             } 
  10.             obj = obj[parts[i]]; 
  11.         } 
  12.         return obj; 
  13.     } 
  14. }; 
  15. MyGolbal.namespace('Book'); //創(chuàng)建Book 
  16. MyGolbal.Book; //讀取 
  17. MyGolbal.namespace('Car').prototype.getWheel = function(){...}  

大多數(shù)模塊依賴加載器或管理器,本質(zhì)上都是將這種模塊定義封裝進(jìn)一個(gè)友好的API

  1. var MyModules = (function Manager() { 
  2.     var modules = {}; 
  3.     function define(name, deps, impl) { 
  4.         for(var i=0; i<deps.length; i++){ 
  5.             deps[i] = modules[deps[i]]; 
  6.         } 
  7.         modules[name] = impl.apply(impl,deps); 
  8.     } 
  9.     function get(name) { 
  10.         return modules[name]; 
  11.     } 
  12.     return { 
  13.         define: define, 
  14.         get: get 
  15.     }; 
  16. })();  

以上代碼的核心是modules[name] = impl.apply(impl,deps);,為了模塊的定義引入了包裝函數(shù)(可以傳入任何依賴),并且將模塊的API存儲(chǔ)在一個(gè)根據(jù)名字來管理的模塊列表modules對(duì)象中;

使用模塊管理器MyModules來管理模塊:

  1. MyModules.define('bar',[],function () { 
  2.     function hello(who) { 
  3.         return 'let me introduce: '+who; 
  4.     } 
  5.     return
  6.         hello: hello 
  7.     }; 
  8. }); 
  9. MyModules.define('foo',['bar'],function (bar) { 
  10.     var hungry = 'hippo'
  11.     function awesome() { 
  12.         console.log(bar.hello(hungry).toUpperCase()); 
  13.     } 
  14.     return { 
  15.         awesome: awesome 
  16.     }; 
  17. }); 
  18. var foo = MyModules.get('foo'); 
  19. foo.awesome();//LET ME INTRODUCE: HIPPO  

異步模塊定義(AMD):

  1. define('my-books', ['dependency1','dependency2'],  
  2.     function (dependency1, dependency2) { 
  3.         var Books = {}; 
  4.         Books.author = {author: 'Mr.zakas'}; 
  5.         return Books; //返回公共接口API 
  6.     } 
  7. );  

通過調(diào)用全局函數(shù)define(),并給它傳入模塊名字、依賴列表、一個(gè)工廠方法,依賴列表加載完成后執(zhí)行這個(gè)工廠方法。AMD模塊模式中,每一個(gè)依賴都會(huì)對(duì)應(yīng)到獨(dú)立的參數(shù)傳入到工廠方法里,即每個(gè)被命名的依賴最后都會(huì)創(chuàng)建一個(gè)對(duì)象被傳入到工廠方法內(nèi)。模塊可以是匿名的(即可以省略第一個(gè)參數(shù)),因?yàn)槟K加載器可以根據(jù)JavaScript文件名來當(dāng)做模塊名字。要使用AMD模塊,需要通過使用與AMD模塊兼容的模塊加載器,如RequireJS、Dojo來加載AMD模塊 

  1. requre(['my-books'] , function(books){ 
  2.             books.author; 
  3.             ... 
  4.    } 
  5.  

以上所說的模塊都是是基于函數(shù)的模塊,它并不是一個(gè)能被穩(wěn)定識(shí)別的模式(編譯器無法識(shí)別),它們的API語義只是在運(yùn)行時(shí)才會(huì)被考慮進(jìn)來。因此可以在運(yùn)行時(shí)修改一個(gè)模塊的API

未來的模塊機(jī)制

ES6為模塊增加了一級(jí)語法支持,每個(gè)模塊都可以導(dǎo)入其它模塊或模塊的特定API成員,同樣也可以導(dǎo)出自己的API成員;ES6的模塊沒有‘行內(nèi)’格式,必須被定義在獨(dú)立的文件中(一個(gè)文件一個(gè)模塊)ES6的模塊API更加穩(wěn)定,由于編譯器可以識(shí)別,在編譯時(shí)就檢查對(duì)導(dǎo)入的API成員的引用是否真實(shí)存在。若不存在,則編譯器會(huì)在運(yùn)行時(shí)就拋出‘早期’錯(cuò)誤,而不會(huì)像往常一樣在運(yùn)行期采用動(dòng)態(tài)的解決方案;

bar.js

  1. function hello(who) { 
  2.     return 'let me introduce: '+who; 
  3. export hello; //導(dǎo)出API: hello  

foo.js

  1. //導(dǎo)入bar模塊的hello() 
  2. import hello from 'bar'
  3.  
  4. var hungry = 'hippo'
  5. function awesome() { 
  6.     console.log(hello(hungry).toUpperCase()); 
  7. export awesome;//導(dǎo)出API: awesome  

baz.js

  1. //完整導(dǎo)入foo和bar模塊 
  2. module foo from 'foo'
  3. module bar from 'bar'
  4. foo.awesome();  
  1. import可以將一個(gè)模塊中的一個(gè)或多個(gè)API導(dǎo)入到當(dāng)前作用域中,并分別綁定在一個(gè)變量上;
  2. module會(huì)將整個(gè)模塊的API導(dǎo)入并綁定到一個(gè)變量上;
  3. export會(huì)將當(dāng)前模塊的一個(gè)標(biāo)識(shí)符(變量、函數(shù))導(dǎo)出為公共API;
  4. 模塊文件中的內(nèi)容會(huì)被當(dāng)做好像包含在作用域閉包中一樣來處理,就和函數(shù)閉包模塊一樣;
責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2019-08-28 16:18:39

JavaScriptJS前端

2020-12-30 11:22:11

Node.js前端模塊

2012-11-08 10:21:41

JSrequireJavaScript

2012-11-08 09:45:44

JavaScriptrequireJS

2020-09-17 10:30:21

前端模塊化組件

2020-09-18 09:02:32

前端模塊化

2022-09-05 09:01:13

前端模塊化

2023-06-28 08:12:49

Python代碼重構(gòu)

2022-09-21 11:51:26

模塊化應(yīng)用

2013-08-20 15:31:18

前端模塊化

2017-05-18 10:23:55

模塊化開發(fā)RequireJsJavascript

2015-10-10 11:29:45

Java模塊化系統(tǒng)初探

2022-03-11 13:01:27

前端模塊

2010-05-28 10:31:28

模塊化IT

2019-12-02 16:05:10

前端模塊化JavaScript

2021-07-14 09:26:51

UPS電源模塊化

2023-05-24 10:35:11

Node.jsES模塊

2011-05-13 15:54:50

C模塊化

2010-08-13 15:48:38

Flex模塊化

2023-12-18 14:56:00

模塊化單體系統(tǒng)數(shù)據(jù)庫
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)