js模塊化
什么是模塊化
將復雜的程序,按照一定的規(guī)范封裝成幾個文件,并組合在一起。實現(xiàn)數(shù)據(jù)內(nèi)部的數(shù)據(jù)、函數(shù)實現(xiàn)是私有的,外部不可修改,只是向外暴露一些接口跟其他模塊通信。
按照這種方式編碼的項目,稱之為模塊化。模塊化的好處
1.防止命名沖突
2.代碼分離
3.代碼復用性高
4.維護性高
模塊化的發(fā)展
- 全局 function 模式
-
module1.js
//數(shù)據(jù) let data = 'labmen' //操作數(shù)據(jù)的函數(shù) function foo() { console.log(`foo() ${data}`) } function bar() { console.log(`bar() ${data}`) } -
module2.js
let data2 = 'other data'; function foo() { //這里與另一個模塊中的函數(shù)沖突了 console.log(`foo() ${data2}`) } -
test.html
<script type="text/javascript" src="module1.js"></script> <script type="text/javascript" src="module2.js"></script> <script type="text/javascript"> let data = "我是修改后的數(shù)據(jù)" foo() bar() </script> -
說明:
- 全局函數(shù)模式: 將不同的功能封裝成不同的全局函數(shù)
- 問題: Global被污染了, 很容易引起命名沖突
- namespace 模式(命名空間)
-
module1.js
let myModule = { data: 'module1 labmen', foo() { console.log(`foo() ${this.data}`) }, bar() { console.log(`bar() ${this.data}`) } } -
module2.js
let myModule2 = { data: 'module2 labmen', foo() { console.log(`foo() ${this.data}`) }, bar() { console.log(`bar() ${this.data}`) } } -
test.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() //可以直接修改模塊內(nèi)部的數(shù)據(jù) myModule.data = 'other data' myModule.foo() </script> -
說明
- namespace 模式: 簡單對象封裝
- 作用: 減少了全局變量
- 問題: 依然可以修改模塊內(nèi)部代碼,不安全
- IIFE 模式
-
module1.js
(function () { //數(shù)據(jù) let data = 'labmen' //操作數(shù)據(jù)的函數(shù) function foo() { //向外暴露的內(nèi)部私有函數(shù) console.log(`foo() ${data}`) } function bar() {//向外暴露的內(nèi)部私有函數(shù) console.log(`bar() ${data}`) otherFun() //內(nèi)部調(diào)用 } function otherFun() { //未暴露的內(nèi)部私有函數(shù) console.log('otherFun()') } //暴露行為 window.myModule = {foo, bar} })() -
test.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 不能訪問模塊內(nèi)部數(shù)據(jù) myModule.data = 'xxxx' //并不是修改的模塊內(nèi)部的data myModule.foo() //未受影響 </script> -
說明:
- IIFE模式: 匿名函數(shù)自調(diào)用(閉包)
- IIFE : immediately-invoked function expression(立即調(diào)用函數(shù)表達式)
- 作用: 數(shù)據(jù)是私有的, 外部只能通過暴露的方法操作
- 問題: 如果當前這個模塊依賴另一個模塊怎么辦?
- IIFE 模式增強
引入jquery到項目中
-
module4.js
(function (window, $) { //數(shù)據(jù) let data = 'labmen' //操作數(shù)據(jù)的函數(shù) function foo() { //用于暴露有函數(shù) console.log(`foo() ${data}`) $('body').css('background', 'red') } function bar() {//用于暴露有函數(shù) console.log(`bar() ${data}`) otherFun() //內(nèi)部調(diào)用 } function otherFun() { //內(nèi)部私有的函數(shù) 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模式增強 : 引入依賴
- 這就是現(xiàn)代模塊實現(xiàn)的基石
- 頁面加載多個js的問題
-
頁面:
<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> <script type="text/javascript" src="module5.js"></script> <script type="text/javascript" src="module6.js"></script> <script type="text/javascript" src="module7.js"></script> <script type="text/javascript" src="module8.js"></script> <script type="text/javascript" src="module9.js"></script> <script type="text/javascript" src="module10.js"></script> <script type="text/javascript" src="module11.js"></script> <script type="text/javascript" src="module12.js"></script> -
說明
- 一個頁面需要引入多個js文件
- 問題:
- 請求過多
- 依賴模糊
- 難以維護
- 這些問題可以通過現(xiàn)代模塊化編碼和項目構(gòu)建來解決