ES6模块化规范
ES6 模块化规范是一个官方标准的规范,它是在语言标准的层面上实现了模块化功能,是目前最流行的模块化规范,且浏览器与服务端均支持该规范。
1、初体验
新建:school.js
export const name = "清华大学";
export const slogan = "是中国最难考的大学吗?";
export function getTel(){
return "010-89898989";
}
function getCities(){
return ["北京","上海","天津"];
}
新建:student.js
export const name = "张三";
export const motto = "明天会更好";
export function getTel(){
return "13201567876";
}
export function getHobby(){
return ["打篮球","踢足球","上网"];
}
在以上两个js文件中,都使用了
export
来暴露数据。
新建:main.js
import * as school from "./school.js";
console.log(school);
console.log(school.name);
在
main.js
中通过import
关键字导入暴露的数据。*
代表导入模块下所有的暴露数据。
新建:index.html
,并引入main.js
文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="main.js" type="module"></script>
</head>
<body>
</body>
</html>
因为
main.js
是一个模块化的js,所以引入的时候必须用type="module"
否则将不能识别模块化。
运行index.html
结果如下:

2、Node中运行ES6模块的两种方式
2.1、通过修改js文件扩展名的方式让模块化的js能在Node下运行。
将.js
的扩展名改成.mjs
。然后直接运行。

2.2、通过增加package.json配置文件的方式使模块化的js能在Node下运行。
在项目目录下新增package.json
文件:
{
"type": "module"
}

3、导出数据
ES6 模块化提供3种导出方式:分别导出、统一导出、默认导出。
3.1、分别导出
export const name = "清华大学";
export const slogan = "是中国最难考的大学吗?";
export function getTel(){
return "010-89898989";
}
function getCities(){
return ["北京","上海","天津"];
}
像上面这种,给每一个需要导出的数据前面加
export
关键字的导出形式就是分别导出。
3.2、统一导出
const name = "清华大学";
const slogan = "是中国最难考的大学吗?";
function getTel(){
return "010-89898989";
}
function getCities(){
return ["北京","上海","天津"];
}
//使用统一导出的方式暴露数据
export { name, slogan, getTel };
在以上的代码中,
export { name, slogan, getTel };
这句代码就是统一导出的方式暴露数据。相较于分别导出的方式来说,统一导出的方式不用给每个需要导出的数据前面加export
关键字,而在代码最后通过一行简单的代码就实现了数据的导出。
3.3、默认导出
const name = "清华大学";
const slogan = "是中国最难考的大学吗?";
function getTel(){
return "010-89898989";
}
function getCities(){
return ["北京","上海","天津"];
}
//默认导出
export default {name, slogan, getTel};
以上代码中
export default {name, slogan, getTel};
是使用默认导出的方法暴露数据。这种数据被绑定在一个default
属性上。在调用的时候区别于其他的方式,需要在default属性上来获取暴露的数据:import * as school from "./school.js"; console.log(school); //要使用:school.default.name来获取暴露的数据,而不是school.name console.log(school.default.name);

3.4、以上三种方式可以混合使用
export const name = "清华大学";//使用了分别导出
const slogan = "是中国最难考的大学吗?";
function getTel(){
return "010-89898989";
}
function getCities(){
return ["北京","上海","天津"];
}
//使用了统一导出
export { slogan };
//使用了默认导出
export default {getTel};
以上代码中使用了分别导出、统一导出和默认导出三种方式。

4、导入数据
对于 ES6模块化来说,使用何种导入方式,要根据导出方式决定。
4.1、导入全部(通用)
import * as school from "./school.js";
获取导入数据的方式:
school.xxx
或school.default.xxx
(默认暴露的情况下)
4.2、命名导入(对应导出方式:分别导出、统一导出)
school.js
代码:
const name = "清华大学";
const slogan = "是中国最难考的大学吗?";
function getTel(){
return "010-89898989";
}
function getCities(){
return ["北京","上海","天津"];
}
export {name, slogan};//使用了统一导出的方式
命名导入:
import {name, slogan} from "./school.js";
console.log(name);
console.log(slogan);
命名导入可以使用
as
关键字来重命名:import {name as schoolName, slogan as schoolSlogan} from "./school.js"; console.log(schoolName); console.log(schoolSlogan);
运行结果:

4.3、默认导入(对应导出方式:默认导出)
schoo.js
代码:
const name = "清华大学";
const slogan = "是中国最难考的大学吗?";
function getTel(){
return "010-89898989";
}
function getCities(){
return ["北京","上海","天津"];
}
//使用默认导出
export default{name, slogan, getTel};
默认引入:
import school from "./school.js";
console.log(school);
运行结果:

4.4、不同导入方式可以混用
school.js
代码:
export const name = "清华大学";//使用分别导出
const slogan = "是中国最难考的大学吗?";
function getTel(){
return "010-89898989";
}
function getCities(){
return ["北京","上海","天津"];
}
export {slogan};//使用统一导出
export default{getTel};//使用默认导出
//默认导出的时候如果只有一个数据可以省略花括号:export default getTel;
混合导入:
import school,{name, slogan} from "./school.js";
console.log(school);
console.log(name);
console.log(slogan);
运行结果:

4.5、动态导入(通用)
在特定时间点或特定操作下导入模块。
例如:页面上有一个按钮,用户点击后导入模块。
在页面中添加一个按钮:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="main.js" type="module"></script>
</head>
<body>
<p>点击按钮导入模块</p>
<button id="btn">导入模块</button>
</body>
</html>
main.js
中点击按钮导入模块:
//使用动态导入
let btn = document.getElementById("btn");
btn.onclick = async()=>{
const student = await import("./student.js");
console.log(student);
}
运行结果:

4.6、import可以不接收任何数据
例如:有一个文件中的一些代码希望在每次项目启动的时候自动执行。
新建log.js
:
console.log(Math.random());
这个文件的作用是每次都输出一个随机数。没有任何暴露数据。
在main.js
中使用import导入:
import './log.js';
运行结果:

5、ES6的数据引用问题
data.js
:
let sum = 1;
function increment(){
sum += 1;
console.log('data',sum);
}
export {sum, increment};
在main.js
中导入并使用:
import {sum, increment} from './data.js';
console.log(sum);
increment();
increment();
console.log(sum);
运行结果:

在模块中定义需要导出的数据的时候,需要使用常量,避免在使用过程中值被改变。