ES6 模块化规范
ES6模块化规范是一个官方标准的规范, 在语言标准的层面上实现了模块化功能
是目前最流行的模块化规范, 且浏览器与服务端均支持该规范
初步上手
- 导出:
school.js
export const name = '家里蹲大学'
export const slogan = '吃饭, 睡觉, 打豆豆'
export function getTel() {
return '010-987650321'
}- 导出:
student.js
export const name = '张三'
export const motto = '法外狂徒'
export function getHobby() {
return ['抽烟', '喝酒', '烫头']
}- 导入:
index.js
/*
*: 全部
as: 作为
school / student 名称
导入 school.js / school.js 中全部模块, 名称叫做 school / student
*/
import * as school from './school.js'
import * as student from './school.js'
console.log(school)
console.log(student)- 引用:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script type="module" scr="./index.js"></script>
</body>
</html>注意
此时script标签中的type属性必须设置为module, 表示以模块的形式导入
在 Node 中运行 ES6 模块
Node环境在12.x及以上版本
- 方式一: 将
.js文件改完.msj - 方式二: 在同目录新建
package.json文件, 添加"type": "module"
{
"type": "module"
}导出数据
ES6模块化提供了3中导出方式:
- 分别导出
- 统一导出
- 默认导出
- 分别导出
export const name = '张三'
export function getTel() {
return '16612356789'
}- 统一导出
const name = '张三'
function getTel() {
return '16612356789'
}
export { name, getTel }注意
此时export后面的{}不是对象, 只是类似于对象的结构, 若写成: export { name: name }则会报错
- 默认导出
const name = '张三'
function getTel() {
return '16612356789'
}
export default { name, getTel }注意
此时export default后面的{}是对象格式
- 备注: 上述
3中导出方式可以同时使用
// 分别导出
export const name = '张三'
const age = 18
function getTel() {
return '16612356789'
}
// 统一导出
export { age }
// 默认导出
export default { getTel }导入数据
对于ES6模块化来说, 使用哪种导入方式, 取决于导出的方式
- 导入全部(通用)
import * as school from './school.js'- 命名导入, 对应导出方式: 分别导出, 统一导出
import { name, getTel as mobile } from './school.js'- 默认导入, 对应导出方式: 默认导出
import school from './school.js'- 命名导入和默认导入可以混合使用
import name, { getTel } from './school.js'- 动态导入(通用)
btn.onclick = async() => {
const res = await import('./school.js')
console.log(res)
}import可以不接收任何数据
import './school.js'数据引用问题
示例一
以下代码没有使用模块化, 输出结果是什么?
count.js
function count() {
let sum = 1
function increment() {
sum += 1
}
return { sum, increment }
}
const { sum, increment } = count()
console.log(sum)
increment()
increment()
console.log(sum)结论
第一个console.log(sum)输出: 1
第二个console.log(sum)输出: 1
原因: const { sum, increment } = count()中的sum只是结构赋值的新变量名, 与count()函数中的sum没有关系
示例二
以下代码使用CommonJS规范, 输出结果是什么?
count.js
let sum = 1
function increment() {
sum += 1
}
module.exports = { sum, increment }index.js
const { sum, increment } = require('./count.js')
console.log(sum)
increment()
increment()
console.log(sum)结论
第一个console.log(sum)输出: 1
第二个console.log(sum)输出: 1
原因: 跟上例一样, const { sum, increment } = require('./count.js')中的sum只是结构赋值的新变量名, 与count.js中的sum没有关系
示例三
以下代码使用ES6模块化规范, 输出结果是什么?
count.js
let sum = 1
function increment() {
sum += 1
}
export { sum, increment }index.js
import { sum, increment } from './count.js'
console.log(sum)
increment()
increment()
console.log(sum)结论
第一个console.log(sum)输出: 1
第二个console.log(sum)输出: 3
原因: import { sum, increment } from './count.js'中的sum与count.js中的sum是同一块内存空间, 这是ES6中的数据引用(符号绑定)问题
ES6模块化规范规定了不能修改import引入的基本数据类型的值
为了规避意外修改值的情况, 需要使用const sum = 1将sum设置为常量, 不要使用var或let定义变量