在ES6以前,在应用程序的每一个JavaScript中定义的一切都共享一个全局作用域。随着Web应用程序变得更加复杂,JavaScript代码的使用量也开始增加,这一做法会引起问题,如命名冲突和安全问题。ES6的一个目标是解决作用域问题,也为了使JavaScript应用程序显得有序,于是引入了模块。
1、什么是模块
- 模块是自动运行在严格模式下且没有办法退出运行的JavaScript代码。
- 与共享一切架构不同的是:在模块顶部创建的变量不会自动添加到全局共享作用域,这个变量仅在模块的顶级作用域中存在。
- 模块必须导出一些外部代码可以访问的元素,例如变量或函数。
- 模块也可以从其他模块导入绑定。
- 在模块顶部,this的值是undefined;
2、导出的基本语法
可以用export关键字将一部分代码暴露给其他模块;也可以将export放在任何变量、函数或类声明的签名,以将它们从模块导出。
//导出数据
export var color = "red";
export let name = "Nicholas";
export const magicNumber = 7;
//导出函数
export function sum(num1, num2) {
return num1 + num2;
}
//导出类
export class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
}
//这个模块是私有的
function subtract(num1, num2) {
return num1 - num2;
}
///定义一个函数,之后将它导出
function multiply(num1, num2) {
return num1 + num2;
}
export multiply;
导出的函数和类声明需要有一个名称,除非用default关键字,否则不能用这个语法导出匿名函数和类。任何未显式导出的变量、函数或类都是模块私有的,无法从模块外部访问。
3、导入的基本语法
从模块中导出的功能可以通过import关键字在另一个模块中访问,import语句的两个部分分别是:要导入的标识符和标识符应当从哪个模块导入。基本形式:
import { identifier1, identifier2 } from "./example.js";
当从模块中导入一个绑定时,它就好像使用const定义的一样。即无法定义另一个同名变量,也无法在import语句前使用标识符或改变绑定的值。
3.1 导入单个绑定
import { sum } from "./example.js";
console.log(sum(1, 2));//3
sum = 1;//抛出一个错误
尽管example.js导出的函数不止一个,但这个示例只导入了sum()函数。
如果尝试给sum赋新值,结果是抛出一个错误。
为了更好的兼容多个浏览器和Node.js环境,一定要在字符串之前包含 ./ 或../ 来表示要导入的文件。
3.2 导入多个绑定
import { sum, multiply } from "./example.js";
console.log(sum(1, 2));//3
console.log(multiply(2, 3));//6
在这段代码中,从example模块导入2个绑定:sum、multiply。之后使用它们就像在本地定义的一样。
3.3 导入整个模块(命名空间导入)
import * as example from "./example.js";
console.log(example.sum(1, 2));//3
console.log(example.multiply(2, 3));//6
在这段代码中,从example.js中导出的所有绑定被加载到一