Module模块化
1、概念
模块化是指将一个大的JavaScript文件拆分成多个小的文件,每个文件都是一个独立的模块,拥有自己的作用域,并通过export和import语句来导出和导入模块中的成员(如变量、函数、类等)。这种方式有助于减少全局命名空间的污染,提高代码的可维护性和可重用性。
2、基本语法
1. 导出(export)
1. 默认导出
每个模块只能有一个默认导出,使用export default
语句。导入时,可以使用任意名称来接收导出的模块。
//mathUtils.js
// 默认导出一个加法函数
export default function add(a, b) {
return a + b;
}
2. 命名导出
一个模块可以有多个命名导出,使用export
关键字。导入时,必须使用与导出时相同的名称来接收导出的模块。
//stringUtils.js
// 命名导出一个大写转换函数
export function toUpperCase(str) {
return str.toUpperCase();
}
// 命名导出一个小写转换函数
export function toLowerCase(str) {
return str.toLowerCase();
}
//或者写到一起,这样写上方的函数前不必再加export
export {toUpperCase,toLowerCase};
3. 统一导出
可以使用export
关键字后跟一个对象字面量来统一导出多个成员。
//utils.js
const add = (a, b) => a + b;
const subtract = (a, b) => a - b;
// 统一导出多个函数
export { add, subtract as sub };
2. 导入(import)
1. 默认导入
使用import
关键字后跟一个变量名来导入默认导出的模块。
//app.js
// 导入mathUtils.js中默认导出的加法函数
import sum from './mathUtils.js';
console.log(sum(2, 3)); // 输出:5
2. 命名导入
使用import
关键字后跟一个花括号,里面列出要导入的命名导出的成员。
//app.js
// 导入stringUtils.js中命名导出的函数
import { toUpperCase, toLowerCase } from './stringUtils.js';
console.log(toUpperCase('hello')); // 输出:HELLO
console.log(toLowerCase('WORLD')); // 输出:world
3. 统一导入
使用import * as
语法来导入模块中的所有导出,并将它们作为一个对象接收。
//app.js
// 统一导入utils.js中所有导出的成员
import * as utils from './utils.js';
console.log(utils.add(5, 3)); // 输出:8
console.log(utils.sub(5, 3)); // 输出:2,注意这里使用的是导出时的别名sub
3. 注意点
- 对于上述的导入和导出,只是使用了函数作为例子,我们还可以导入和导出其他的数据类型和变量,比如:
//默认导出
//mathUtils.js
function add(a, b) {
return a + b;
}
function substract(a, b) {
return a - b;
}
// 默认导出一个对象,该对象上挂了两个方法
export default { add, substract };
//app.js
//在app.js文件中,使用obj变量来接受对象
import obj from "./mathUtils.js";
//使用该对象上的两个方法
console.log(obj.add(1,2)); //输出:3
console.log(obj.substract(5,3)); //输出:2
- 对于使用了模块化的文件,在html文件中使用时需要加上type=“module”,否则会报错.
<!-- 导入模块化的js文件 -->
<script src="app.js" type="module"></script>
<!-- 如果不写type="module" 会报 Cannot use import statement outside a module 错误 -->
3、特点
- 静态结构:ES6模块化的导入和导出是静态的,意味着在编译时就能确定模块之间的依赖关系,有助于优化加载性能。
- 自动严格模式:ES6模块自动运行在严格模式下,即使模块内部没有显式声明
use strict
。 - 防止命名冲突:每个模块都有自己的命名空间,因此可以避免命名冲突。
- 代码复用:模块化的代码更容易在不同的项目中进行复用。
- 高维护性:每个模块都可以独立开发和测试,降低了代码之间的耦合度,提高了代码的可维护性。
4、与其他模块化规范的比较
与CommonJS和AMD等模块化规范相比,ES6模块化具有以下优势:
- 语法更简洁:使用
export
和import
关键字来导出和导入模块成员,比CommonJS的require
和module.exports
更简洁。 - 静态加载:在编译时就处理模块依赖关系,比CommonJS的运行时加载更高效。
- 浏览器和服务器通用:ES6模块化不仅适用于浏览器端,也适用于Node.js等服务器端环境。