# 模塊化進化史教程
## 全局function模式
### 說明
全局函數模式: 將不同的功能封裝成不同的全局函數
### 問題:
Global被污染了, 很容易引起命名沖突
依賴模糊,而且順序不可以亂
### module1.js
```
//數據
let data = 'wolfcode.cn'
//操作數據的函數
function foo() {
console.log(`foo() ${data}`)
}
function bar() {
console.log(`bar() ${data}`)
}
```
### module2.js
```
let data2 = 'other data'
function foo() { //與另一個模塊中的函數沖突了
console.log(`foo() ${data2}`)
}
```
### test1.html
```
<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript">
let data = "修改后的數據"
foo()
bar()
</script>
```
## namespace模式(命名空間類似java)
### module1.js
```
let myModule = {
data: 'atguigu.com',
foo() {
console.log(`foo() ${this.data}`)
},
bar() {
console.log(`bar() ${this.data}`)
}
}
```
### module2.js
```
let myModule2 = {
data: 'wolfcode.cn2222',
foo() {
console.log(`foo() ${this.data}`)
},
bar() {
console.log(`bar() ${this.data}`)
}
}
```
### test2.html
```
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript" src="module22.js"></script>
<script type="text/javascript">
myModule.foo()
myModule.bar()
myModule2.foo()
myModule2.bar()
myModule.data = 'other data' //能直接修改模塊內部的數據
myModule.foo()
</script>
```
### 說明
namespace模式: 簡單對象封裝
作用: 減少了全局變量,
問題: 不安全,內部變量都可以被修改
## IIFE模式(匿名函數自執行)
module3.js
```
(function (window) {
//數據
let data = 'wolfcode.cn'
//操作數據的函數
function foo() { //用于暴露有函數
console.log(`foo() ${data}`)
}
function bar() {//用于暴露有函數
console.log(`bar() ${data}`)
otherFun() //內部調用
}
function otherFun() { //內部私有的函數
console.log('otherFun()')
}
//暴露行為
window.myModule = {foo, bar}
})(window)
```
test3.html
```
<script type="text/javascript" src="module3.js"></script>
<script type="text/javascript">
myModule.foo()
myModule.bar()
//myModule.otherFun() //myModule.otherFun is not a function
console.log(myModule.data) //undefined 不能訪問模塊內部數據
myModule.data = 'xxxx' //不是修改的模塊內部的data
myModule.foo() //沒有改變
</script>
```
### 說明:
IIFE模式: 匿名函數自調用(閉包)
IIFE : immediately-invoked function expression(立即調用函數表達式)
作用: 數據是私有的, 外部只能通過暴露的方法操作
問題: 如果當前這個模塊依賴另一個模塊怎么辦?
## IIFE模式增強(jquery方式)
引入jquery到項目中
module4.js
```
(function (window, $) {
//數據
let data = 'wolfcode.cn'
//操作數據的函數
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)
```
test4.html
```
<script type="text/javascript" src="jquery-1.10.1.js"></script>
<script type="text/javascript" src="module4.js"></script>
<script type="text/javascript">
myModule.foo()
</script>
```
### 說明
IIFE模式增強 : 引入依賴
這就是現代模塊實現的基石
頁面:
```
<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript" src="module3.js"></script>
<script type="text/javascript" src="module4.js"></script>
```
說明
一個頁面需要引入多個js文件
### 問題:
請求過多
依賴模糊
難以維護
這些問題可以通過現代模塊化編碼和項目構建來解決