1.模塊的寫法javascript
a、原始寫法:html
function m1() {..........} function m2() {..........}
這兩個函數組成一個模塊,使用時直接調用,可是這樣明顯污染全局環境,沒法保證不與其餘的模塊發生變量名衝突,而且這樣也看不出來各個模塊之間的依賴關係。java
b、後來寫成對象:jquery
var module1 = new Object({ _count : 0, m1 : function (){ //... }, m2 : function (){ //... } });
這樣就寫module.m1(); 可是這樣暴露了全部模塊成員,內部代碼能夠被外部改寫。好比外部代碼能夠直接改變內部計數的值 :module1._count =5;數組
c、使用當即執行函數能夠達到不暴露私有成員變量的目的。瀏覽器
var module1 = (function(){ var _count = 0; var m1 = function(){ //... }; var m2 = function(){ //... }; return { m1 : m1, m2 : m2 }; })();
d、後來又有了寬放大的模式服務器
var module1 = ( function (mod){ //... return mod; })(window.module1 || {});
2.出現模塊化規範,目前有 :CommonJS模塊、AMD模塊還有CMD模塊 幾種規範。異步
a、CommonJS規範同步加載模塊,這對服務器端不是一個問題,由於全部的模塊都存放在本地硬盤,能夠同步加載完成,等待時間就是硬盤的讀取時間。可是,對於瀏覽器,這倒是一個大問題,由於模塊都放在服務器端,等待時間取決於網速的快慢,可能要等很長時間,瀏覽器處於"假死"狀態。所以,瀏覽器端的模塊,不能採用"同步加載"(synchronous),只能採用"異步加載"(asynchronous)。這就是AMD規範誕生的背景。
async
var math = require('math'); math.add(2, 3)
b、主要講AMD異步加載模塊加載採用異步方式加載模塊,模塊的加載不影響它後面語句的運行。全部依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成以後,這個回調函數纔會運行。
AMD也採用require加載模塊 require([module], callback);第一個參數[module],是一個數組,裏面的成員就是要加載的模塊;第二個參數callback,則是加載成功以後的回調函數
模塊化
require(['math'], function (math) { math.add(2, 3); });
math.add()與math模塊加載不是同步的,瀏覽器不會發生假死。因此很顯然,AMD比較適合瀏覽器環境。require.js這個JavaScript的庫實現了AMD規範
3.require.js用法
a、開始引用js文件
<script src="1.js"></script> <script src="2.js"></script> <script src="3.js"></script> <script src="4.js"></script>
這樣的方式加載有兩個缺點:加載的時候,瀏覽器會中止網頁渲染,加載文件越多,網頁失去響應的時間就會越長(解決方法在下邊);其次,因爲js文件之間存在依賴關係,所以必須嚴格保證加載順序
b、require.js解決了這個問題 <script src="js/require.js" defer async="true" ></script>
async屬性代表這個文件須要異步加載,避免網頁失去響應。IE不支持這個屬性,只支持defer,因此把defer也寫上。加載require.js之後就須要 加載咱們本身的代碼了,寫一個main.js 這就至關於c語言的main()入口;
<script src="js/require.js" data-main="js/main"></script> data-main屬性的做用是,指定網頁程序的主模塊
main.js ---------> require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){ // some code here });
require()函數接受兩個參數。第一個參數是一個數組,表示所依賴的模塊,上例就是['moduleA', 'moduleB', 'moduleC'],即主模塊依賴這三個模塊;第二個參數是一個回調函數,當前面指定的模塊都加載成功後,它將被調用。加載的模塊會以參數形式傳入該函數,從而在回調函數內部就可使用這些模塊。
require()異步加載moduleA,moduleB和moduleC,瀏覽器不會失去響應;它指定的回調函數,只有前面的模塊都加載成功後,纔會運行,解決了依賴性的問題。
c、自定義模塊的加載行爲 :使用require.config()方法進行定義;寫在main.js的頭部。
require.config({ paths: { // 或者寫上baseUrl: "js/lib",下邊就不用寫lib "jquery": "lib/jquery.min", "underscore": "lib/underscore.min", "backbone": "lib/backbone.min" } });
若是加載多個模塊,就會發出屢次HTTP請求,會影響網頁的加載速度。所以,require.js提供了一個優化工具,當模塊部署完畢之後,能夠用這個工具將多個模塊合併在一個文件中,減小HTTP請求數。
4.加載方式完了,而後就是本身寫的模塊 應該用AMD規範進行,寫模塊必須採用特定的define()函數來定義;
---------------->// math.js模塊 define(function (){ var add = function (x,y){ return x+y; }; return { add: add }; });
b、若是這個模塊依賴其餘的模塊怎麼辦?
---------------->// math.js模塊 define(['myLib'], function(myLib){ function foo(){ myLib.doSomething(); } return { foo : foo }; });
5.不少的庫的模塊並不符合AMD規範那麼怎麼進行加載呢?那加載他們以前必需要先定義他們的特徵,好比加載underscore和backbone
require.config({ shim: { 'underscore':{ exports: '_' }, 'backbone': { deps: ['underscore', 'jquery'], exports: 'Backbone' } } });
require.config()接受一個配置對象,這個對象除了有前面說過的paths屬性以外,還有一個shim屬性,專門用來配置不兼容的模塊。具體來講,每一個模塊要定義(1)exports值(輸出的變量名),代表這個模塊外部調用時的名稱;(2)deps數組,代表該模塊的依賴性。
參照文檔:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html(阮一峯) 本身理解