目录
一、模块化概述
1.概念
随着前端应用日趋复杂,项目代码也大量膨胀,模块化就是一种最主流的代码组织方式,一个模块就是一个实现特定功能的文件,它通过把我们的复杂代码按照功能的不同,划分为不同的模块单独维护的这种方式,去提高我们的开发效率,降低维护成本。要用什么功能就加载什么模块模块化开发是当下最重要的前端开发范式之一,其只是思想,不包含具体实现。
2.模块化开发的好处
- 避免变量污染、命名冲突等
- 提高代码复用率
- 提高维护性
- 依赖关系的管理
3.模块化演变过程
(1)文件划分方式
- 将每个功能和相关的一些状态数据单独存放在不同的文件当中,此时一个文件就是一个独立的模块。然后将这个模块引入页面当中,直接调用模块中的成员(变量/函数),一个script标签就对应一个模块,所有模块都在全局范围内工作。
html文件:
<script type='text/javascript' src='module1.js'></script>
<script type='text/javascript'>
foo();
bar();
msg='NBA'; //会污染全局变量
foo();
</script>
js文件:
/**
* 全局函数模式: 将不同的功能封装成不同的全局函数
* 问题: Global被污染了, 很容易引起命名冲突
*/
let msg = 'modulel'
function foo() {
console.log('foo()', msg);
}
function bar() {
console.log('bar()', msg);
}
输出结果:
- 缺点:
- 污染全局作用域
- 命名冲突问题
- 无法管理模块依赖关系
(2)对象封装
- 将所有模块成员封装在一个对象中,当要使用的时候就调用这个对象的属性。
html文件:
<script type='text/javascript' src='module1.js'></script>
<script type='text/javascript'>
obj.foo();
obj.msg = 'NBA';
obj.foo();
</script>
js文件:
/**
* namespace模式: 简单对象封装
* 作用: 减少了全局变量
* 问题: 不安全(数据不是私有的, 外部可以直接修改)
*/
let obj = {
msg: 'atguigu',
foo() {
console.log('foo()', this.msg);
}
};
结果:
- 缺点:
- 没有私有空间,模块成员仍然可以在外部被访问或修改
- 无法管理模块依赖关系
(3)IIFE模式(立即执行函数)
- 采用该方式为模块提供私有空间,将模块中每个成员都放在一个函数提供对的私有作用域中,可确保私有成员的安全。私有成员只能在模块成员内通过闭包的形式访问。
html文件:
<script type='text/javascript' src='module3.js'></script>
<script type='text/javascript'>
msg='NBA';
console.log(msg);//此时不会修改函数内部msg,相当于给window添加了msg属性
obj.foo(); //此时obj是window的一个对象,可以调用foo属性
</script>
js文件:
/**
* IIFE模式: 匿名函数自调用(闭包)
* IIFE : immediately-invoked function expression(立即调用函数表达式)
* 作用: 数据是私有的, 外部只能通过暴露的方法操作
* 问题: 如果当前这个模块依赖另一个模块怎么办?
*/
//IIFE模式
(function (window) {
let msg = 'atguigu';
function foo() {
console.log('foo()', msg);
}
window.obj = {
foo } //向window暴露一个对象
})(window)
结果:
(4)IIFE模式增强
- 引入jQuery依赖包
html文件:
<script type='text/javascript' src='jquery-1.10.1.js'></script>
<script type='text/javascript' src='module4.js'></script>
<script type='text/javascript'>
fn();
</script>
js文件:
/**
* IIFE模式增强 : 引入依赖
* 这就是现代模块实现的基石
*/
(function(window,$){
let msg='atguigu';
function foo() {
console.log('foo()',msg);
}
window.fn=foo; //向window添加方法
$('body').css('background','red'); //改变body的颜色
})(window,jQuery);
结果: