全局function模式 : 將不一樣的功能封裝成不一樣的全局函數javascript
function m1(){
//...
}
function m2(){
//...
}
複製代碼
namespace模式 : 簡單對象封裝css
let myModule = {
data: 'www.baidu.com',
foo() {
console.log(`foo() ${this.data}`)
},
bar() {
console.log(`bar() ${this.data}`)
}
}
myModule.data = 'other data' //能直接修改模塊內部的數據
myModule.foo() // foo() other data
複製代碼
這樣的寫法會暴露全部模塊成員,內部狀態能夠被外部改寫。html
IIFE模式:匿名函數自調用(閉包)前端
// index.html文件
<script type="text/javascript" src="module.js"></script>
<script type="text/javascript"> myModule.foo() myModule.bar() console.log(myModule.data) //undefined 不能訪問模塊內部數據 myModule.data = 'xxxx' //不是修改的模塊內部的data myModule.foo() //沒有改變 </script>
複製代碼
// module.js文件
(function(window) {
let data = 'www.baidu.com'
//操做數據的函數
function foo() {
//用於暴露有函數
console.log(`foo() ${data}`)
}
function bar() {
//用於暴露有函數
console.log(`bar() ${data}`)
otherFun() //內部調用
}
function otherFun() {
//內部私有的函數
console.log('otherFun()')
}
//暴露行爲
window.myModule = { foo, bar } //ES6寫法
})(window)
複製代碼
最後獲得的結果:java
IIFE模式加強 : 引入依賴jquery
這就是現代模塊實現的基石webpack
// module.js文件
(function(window, $) {
let data = 'www.baidu.com'
//操做數據的函數
function foo() {
//用於暴露有函數
console.log(`foo() ${data}`)
$('body').css('background', 'red')
}
function bar() {
//用於暴露有函數
console.log(`bar() ${data}`)
otherFun() //內部調用
}
function otherFun() {
//內部私有的函數
console.log('otherFun()')
}
//暴露行爲
window.myModule = { foo, bar }
})(window, jQuery)
複製代碼
// index.html文件
<!-- 引入的js必須有必定順序 -->
<script type="text/javascript" src="jquery-1.10.1.js"></script>
<script type="text/javascript" src="module.js"></script>
<script type="text/javascript"> myModule.foo() </script>
複製代碼
上例子經過jquery方法將頁面的背景顏色改爲紅色,因此必須先引入jQuery庫,就把這個庫看成參數傳入。這樣作除了保證模塊的獨立性,還使得模塊之間的依賴關係變得明顯。web
首先咱們要依賴多個模塊,那樣就會發送多個請求,致使請求過多編程
咱們不知道他們的具體依賴關係是什麼,也就是說很容易由於不瞭解他們之間的依賴關係致使加載前後順序出錯。瀏覽器
以上兩種緣由就致使了很難維護,極可能出現牽一髮而動全身的狀況致使項目出現嚴重的問題。 模塊化當然有多個好處,然而一個頁面須要引入多個js文件,就會出現以上這些問題。而這些問題能夠經過模塊化規範來解決,下面介紹開發中最流行的commonjs, AMD, ES6, CMD規範。
1.CommonJS
2.AMD
定義暴露模塊:
//定義沒有依賴的模塊
define(function(){
return 模塊
})
複製代碼
//定義有依賴的模塊
define(['module1', 'module2'], function(m1, m2){
return 模塊
})
複製代碼
引入使用模塊:
require(['module1', 'module2'], function(m1, m2){
使用m1/m2
})
複製代碼
AMD模塊定義的方法很是清晰,不會污染全局環境,可以清楚地顯示依賴關係。
3.CMD
CMD規範基本語法
定義暴露模塊:
//定義沒有依賴的模塊
define(function(require, exports, module){
exports.xxx = value
module.exports = value
})
複製代碼
//定義有依賴的模塊
define(function(require, exports, module){
//引入依賴模塊(同步)
var module2 = require('./module2')
//引入依賴模塊(異步)
require.async('./module3', function (m3) {
})
//暴露模塊
exports.xxx = value
})
複製代碼
define(function (require) {
var m1 = require('./module1')
var m4 = require('./module4')
m1.show()
m4.show()
})
複製代碼
4.ES6模塊化
ES6模塊化語法
/** 定義模塊 math.js **/
var basicNum = 0;
var add = function (a, b) {
return a + b;
};
export { basicNum, add };
/** 引用模塊 **/
import { basicNum, add } from './math';
function test(ele) {
ele.textContent = add(99 + basicNum);
}
複製代碼
export default命令,爲模塊指定默認輸出。
// export-default.js
export default function () {
console.log('foo');
}
// import-default.js
import customName from './export-default';
customName(); // 'foo'
複製代碼
ES6 模塊與 CommonJS 模塊的差別
它們有兩個重大差別:
① CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。
② CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。
ES6 在語言標準的層面上,實現了模塊功能,並且實現得至關簡單,徹底能夠取代 CommonJS 和 AMD 規範,成爲瀏覽器和服務器通用的模塊解決方案。
雖然依賴了某個模塊,但其實只使用其中的某些功能。經過 tree-shaking,將沒有使用的模塊搖掉,這樣來達到刪除無用代碼的目的。