一、模块化的理解
1.什么是模块?
- 将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起
- 块的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信
2.模块化的进化过程
- 全局function模式 : 将不同的功能封装成不同的全局函数
- 编码: 将不同的功能封装成不同的全局函数
- 问题: 污染全局命名空间, 容易引起命名冲突或数据不安全,而且模块成员之间看不出直接关系
1 2 3 4 5 6
| function m1(){ } function m2(){ }
|
- namespace模式 : 简单对象封装
- 作用: 减少了全局变量,解决命名冲突
- 问题: 数据不安全(外部可以直接修改模块内部的数据)
1 2 3 4 5 6 7 8 9 10 11
| let myModule = { data: 'www.baidu.com', foo() { console.log(`foo() ${this.data}`) }, bar() { console.log(`bar() ${this.data}`) } } myModule.data = 'other data' myModule.foo()
|
这样的写法会暴露所有模块成员,内部状态可以被外部改写。
- IIFE模式:匿名函数自调用(闭包)
- 作用: 数据是私有的, 外部只能通过暴露的方法操作
- 编码: 将数据和行为封装到一个函数内部, 通过给window添加属性来向外暴露接口
- 问题: 如果当前这个模块依赖另一个模块怎么办?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <script type="text/javascript" src="module.js"></script> <script type="text/javascript"> myModule.foo() myModule.bar() console.log(myModule.data) myModule.data = 'xxxx' myModule.foo() </script>
(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 } })(window)
|
最后得到的结果:

这就是现代模块实现的基石
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| (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) <!-- 引入的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库,就把这个库当作参数传入。这样做除了保证模块的独立性,还使得模块之间的依赖关系变得明显。
3. 模块化的好处
- 避免命名冲突(减少命名空间污染)
- 更好的分离, 按需加载
- 更高复用性
- 高可维护性