模塊化概念: 實現(xiàn)特定功能的一組方法
原始“類模塊”寫法
function m1(){}
function m2(){}
缺點:污染了全局變量,模塊成員之間沒直接關(guān)系
對象“類模塊”寫法
var module = new Object({
_count:0,
m1:function(){},
m2:function(){}
})
缺點: 使用時直接調(diào)用對象屬性,module.m1(),會暴露所有模塊成員,內(nèi)部狀態(tài)可以被外部改寫
立即執(zhí)行函數(shù)寫法(IIFE)
var module = (function(){
var _count = 0;
var m1 = function(){};
var m2 = function(){}
return{
m1: m1,
m2:m2
}
})();
優(yōu)點:不暴露私有成員,也不造成全局變量污染
此module就是JavaScript模塊的基本寫法
主流模塊規(guī)范
ES6 module.
ES6之前:
- CommonJS
- AMD
CommonJS
- 暴露模塊使用
module.exports和exports - 全局方法
require() - CommonJS范圍不適用于瀏覽器環(huán)境
AMD 和CMD采用
require方式應(yīng)用
瀏覽器的模塊加載,同步容易阻塞,只能異步加載(AMD)
CMD與AMD都是用define()來定義模塊,用require()來引用
AMD:Asynchronous Module Definition
-
采用
define()函數(shù)定義模塊-
define(id,dependencies,factory)-
id字符串 -
dependencies載入的依賴模塊,使用相對路徑,數(shù)組的形式 -
factory工廠方法 返回一個模塊函數(shù)
-
-
- AMD采用
require([module],callback)語句加載模塊 -
滿足AMD規(guī)范的庫:
require.js和curl.js
define(thename, ['Lib'],function(Lib){})
//AMD的模塊加載 不會發(fā)生假死。AMD適合瀏覽器環(huán)境
require(['math'],function(math){ })
CMD: Common Module Definition
-
依賴就近,用的時候再
require - 滿足CMD規(guī)范的庫:seajs
define(name,dependencies,function(require,exports,module){})
define('hello',['jquery'],function(require,exports,module){ //模塊代碼 })
AMD VS CMD
- 均為異步加載模塊
- AMD依賴前置
- CMD就近依賴
ES6 Module標準
- 標準是以import引入模塊,export導(dǎo)出模塊
- node技術(shù)遵循CommonJS規(guī)范,使用require引入模塊,使用
module.exports或exports導(dǎo)出接口
export
- 導(dǎo)出函數(shù)、對象、指定文件(模塊)的原始值
- 命名式導(dǎo)出(名稱導(dǎo)出)
- 默認導(dǎo)出(定義式導(dǎo)出)
- node中是
exports
命名式導(dǎo)出
- 導(dǎo)出多個值,import引用使用相同的名稱。
-
export * from 'article'使用*和from來實現(xiàn)模塊的繼承 - 模塊導(dǎo)出時,可以指定模塊的導(dǎo)出成員
- 導(dǎo)出的成員是類中的共有對象
- 非導(dǎo)出成員是類中私有對象
-
export {name as siteName, domain:domain}模塊導(dǎo)出是as關(guān)鍵字對導(dǎo)出成員進行重命名。 -
export 1導(dǎo)出接口時,必須與模塊內(nèi)部的變量具有意義對應(yīng)關(guān)系。 -
export {a}導(dǎo)出變量值a 即使a被賦值為function也是不允許寫export a這種寫法。 - 模塊中在末尾用一個export導(dǎo)出所有的接口。
export {fun as default, a, b, c}
//一個模塊里這樣寫
export function cube(){}
const foo = Math.PI;
export {foo};
//另一個模塊引用
import {cube, foo} from ...
默認導(dǎo)出
- 定義式導(dǎo)出
- 默認導(dǎo)出只有單一值,可以是函數(shù),類或其他類型的值。
- import 導(dǎo)入比較容易。
-
export default D與export {D as default}
//命名式導(dǎo)出多個模塊
export const foo = Math.sqrt(2) 導(dǎo)出一個常量
export { name1, name2, name3}
export { variable as name1, variable as name, ...nameN }
export let name1,name2, ...nameN
//導(dǎo)出定義的變量和常量
export let name1 = .., name2=...,nameN;
//默認導(dǎo)出,只能導(dǎo)出單個模塊
export default expression;
export default function(){}
export default function name1(){}
export {name2 as default ,...}
//從已存在的模塊,腳本文件..導(dǎo)出
export * from ..;
export {name1, name2} from ....;
export {import1 as name1, import2 as name2...,nameN} from ...
import
- 從已導(dǎo)出的模塊,腳本中導(dǎo)入函數(shù),對象,指定文件的原始值。
- 命名式導(dǎo)入與默認導(dǎo)入
//default
import default Member from "module-name";
//等同于export {a as default}
import * as name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name";
//*導(dǎo)入所有
import defaultMember, * as name from "module-name";
//導(dǎo)入一個模塊不進行任何綁定
import "module-name";
Module.exports VS exports
- Module.exports 全局變量
- exports 局部變量
- 每個js文件創(chuàng)建,都有
var exports = module.exports ={}這倆都指向同一個空對象 - 這倆指向的內(nèi)存地址相同。