1. 為什么要使用模塊化?
背景:如今CPU、瀏覽器性能得到了極大的提升,很多頁面邏輯遷移到了客戶端(表單驗證等),隨著web2.0時代的到來,Ajax技術得到廣泛應用,jQuery等前端庫層出不窮,前端代碼日益膨脹,這與JavaScript發(fā)展初期就是為了實現(xiàn)簡單的頁面交互邏輯的目的相悖。而且,JavaScript卻沒有為組織代碼提供任何明顯幫助,甚至沒有類的概念,更不用說模塊(module)了,JavaScript極其簡單的代碼組織規(guī)范不足以駕馭如此龐大規(guī)模的代碼。
模塊化其主要的目的是為了:
1.解決命名沖突
2.依賴管理
同時模塊化可以提高代碼可讀性,代碼解耦,提高復用性。
2. CMD、AMD、CommonJS 規(guī)范分別指什么?有哪些應用
-
AMD (Asynchronous Module Definition, 異步模塊定義) 指定一種機制,在該機制下模塊和依賴可以異步加載。實際上AMD 是 RequireJS 在推廣過程中對模塊定義的規(guī)范化的產(chǎn)出。
AMD推崇依賴前置,在定義模塊的時候就要聲明其依賴的模塊。
requireJS主要解決兩個問題:
1.多個js文件可能有依賴關系,被依賴的文件需要早于依賴它的文件加載到瀏覽器
2.js加載的時候瀏覽器會停止頁面渲染,加載文件越多,頁面失去響應時間越長
語法
define(id?, dependencies?, factory);
1.id: 定義中模塊的名字,可選;如果沒有提供該參數(shù),模塊的名字應該默認為模塊加載器請求的指定腳本的名字。。
2.依賴dependencies:是一個當前模塊依賴的,已被模塊定義的模塊標識的數(shù)組字面量。 依賴參數(shù)是可選的,如果忽略此參數(shù),它應該默認為["require", "exports", "module"]。然而,如果工廠方法的長度屬性小于3,加載器會選擇以函數(shù)的長度屬性指定的參數(shù)個數(shù)調(diào)用工廠方法。
3.工廠方法factory,模塊初始化要執(zhí)行的函數(shù)或?qū)ο蟆H绻麨楹瘮?shù),它應該只被執(zhí)行一次。如果是對象,此對象應該為模塊的輸出值。
示例://RequireJS: //創(chuàng)建html文件,在<script>標簽中引入Require.js庫,設置data-main屬性: <script src="http://apps.bdimg.com/libs/require.js/2.1.11/require.min.js" data-main="js/main"></script> //test.js define(['jquery',function(){ function testA(){ console.log('hello world') } return { testA:testA } } //加載 require(['test'],function(test){ test.testA() }
-
CMD 即Common Module Definition通用模塊定義,CMD是 SeaJS推廣過程中產(chǎn)生的,SeaJS要解決的問題和requireJS一樣,只不過在模塊定義方式和模塊加載(可以說運行、解析)時機上有所不同。在 CMD 規(guī)范中,一個模塊就是一個文件。
CMD推崇就近依賴,只有在用到某個模塊的時候再去require,即按需加載。
語法:
define([id],[dependency],factory)
前兩參數(shù)和AMD一致,由于CMD推崇依賴就近,通常不在define的第二個參數(shù)中輸入依賴,通常在factory中輸入依賴factory是一個函數(shù),前三個參數(shù)是固定的。
示例:// a.js define(function(require, exports, modules)) { var $ = require('jQurey.2.1.js') // 假設需要使用jQurey var name = 'jrg' fucntion sayName() { console.log(name) } module.exports = sayName // 輸出 } //其他js var sayName = require('./a.js') //相對路徑 var Name = new name() Name.sayName()
-
CommonJS是服務器端模塊的規(guī)范,Node.js采用了這個規(guī)范。Node.JS首先采用了js模塊化的概念。
1.定義模塊 根據(jù)CommonJS規(guī)范,一個單獨的文件就是一個模塊。每一個模塊都是一個單獨的作用域,也就是說,在該模塊內(nèi)部定義的變量,無法被其他模塊讀取,除非定義為global對象的屬性
2.模塊輸出: 模塊只有一個出口,module.exports對象,我們需要把模塊希望輸出的內(nèi)容放入該對象
3.加載模塊: 加載模塊使用require方法,該方法讀取一個文件并執(zhí)行,返回文件內(nèi)部的module.exports對象
示例:
//定義一個a.js文件
var name = "123";
function printName(){
console.log(name)
}
module.exports = {
printName: printName
}//在b.js中引用a.js var b = require('./a'); //接受a.js的exports的值 b.printName() //輸出123