模塊化

模塊化概念: 實現(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.exportsexports
  • 全局方法require()
  • CommonJS范圍不適用于瀏覽器環(huán)境

AMD 和CMD采用require方式應(yīng)用
瀏覽器的模塊加載,同步容易阻塞,只能異步加載(AMD)
CMDAMD都是用 define()來定義模塊,用require()來引用

AMD:Asynchronous Module Definition

  • 采用define()函數(shù)定義模塊
    • define(id,dependencies,factory)
      • id字符串
      • dependencies 載入的依賴模塊,使用相對路徑,數(shù)組的形式
      • factory工廠方法 返回一個模塊函數(shù)
  • AMD采用require([module],callback)語句加載模塊
  • 滿足AMD規(guī)范的庫require.jscurl.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.exportsexports導(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 Dexport {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)存地址相同。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容