ES6 引入了模块化, ES6 的模块化分为导出(export) @与导入(import)两个模块。
ES6模块化特点:
(1)ES6 的模块自动开启严格模式,不管你有没有在模块头部加上 use strict;。
(2) 模块中可以导入和导出各种类型的变量,如函数,对象,字符串,数字,布尔值,类等。
(3) 每个模块都有自己的上下文,每一个模块内声明的变量都是局部变量,不会污染全局作用域。
(4) 每一个模块只加载一次(是单例的), 若再去加载同目录下同文件,直接从内存中读取。
一、export与import基本使用
export 命令用于导出, import 命令 用于导入:
module1.js
// export let name = "孙悟空";
// export let sex = "男";
//或
let name = "孙悟空";
let sex = "男";
export {name,sex};
test1.js
// import { name,sex } from "../export/module1.js";
// console.log(name); //孙悟空
// console.log(sex); //男
//或导入部分变量
import { sex } from "../export/module1.js";
console.log(sex); //男
Demo01.html
<!--
module1.js:模块代码,通过export暴露变量
test1.js:导入module1.js提供的变量
Demo01.html:引入test1.js内容
-->
<script type="module" src="import/test1.js"></script>
二、网页中直接import模块
module1.js
// export let name = "孙悟空";
// export let sex = "男";
//或
let name = "孙悟空";
let sex = "男";
export {name,sex};
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>网页中import模块</title>
</head>
<body>
<h1>姓名:<span id="spanName"></span></h1>
<h1>性别:<span id="spanSex"></span></h1>
</body>
</html>
<!--
module1.js:模块代码,通过export暴露变量
Demo02.html:导入module1.js提供的变量
-->
<script type="module">
import {name,sex} from "./export/module1.js";
document.getElementById("spanName").innerHTML = name;
document.getElementById("spanSex").innerHTML = sex;
</script>
三、as的使用
(1)as在export中的用法:变量使用别名,隐藏模块内部的变量
module2.js:
let name = "孙悟空";
let sex = "男";
export {name as expName,sex as expSex};
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>as在export中的用法</title>
</head>
<body>
<h1>姓名:<span id="spanName"></span></h1>
<h1>性别:<span id="spanSex"></span></h1>
</body>
</html>
<!--
module2.js:模块代码,通过export暴露变量(变量使用别名,隐藏模块内部的变量)
Demo03.html:导入module2.js提供的变量
-->
<script type="module">
import {expName,expSex} from "./export/module2.js";
document.getElementById("spanName").innerHTML = expName;
document.getElementById("spanSex").innerHTML = expSex;
</script>
(2)as在import中的用法:导入多个模块的变量,使用as解决命名冲突。
module1.js
// export let name = "孙悟空";
// export let sex = "男";
//或
let name = "孙悟空";
let sex = "男";
export {name,sex};
module3.js
// export let name = "孙悟空";
// export let sex = "男";
//或
let name = "猪八戒";
let sex = "男";
export {name,sex};
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>as在import中的用法</title>
</head>
<body>
<h1>姓名:<span id="spanName1"></span></h1>
<h1>性别:<span id="spanSex1"></span></h1>
<hr />
<h1>姓名:<span id="spanName2"></span></h1>
<h1>性别:<span id="spanSex2"></span></h1>
</body>
</html>
<!--
module1.js:模块代码(暴露name,sex)
module3.js:模块代码(暴露name,sex)
Demo04.html:导入两个模块的变量,使用as解决命名冲突
-->
<script type="module">
import {name as name1,sex as sex1} from "./export/module1.js";
import {name as name2,sex as sex2} from "./export/module3.js";
document.getElementById("spanName1").innerHTML = name1;
document.getElementById("spanSex1").innerHTML = sex1;
document.getElementById("spanName2").innerHTML = name2;
document.getElementById("spanSex2").innerHTML = sex2;
</script>
四、导入模块中的函数和类
(1)导入模块中的函数
module4.js
// function Add(...items)
// {
// let sum = 0;
// for(let item of items)
// {
// sum += item;
// }
// return sum;
// }
// export{Add};
//或
export function Add(...items)
{
let sum = 0;
for(let item of items)
{
sum += item;
}
return sum;
};
HTML
<script type="module">
//导入函数
import {Add} from './export/module4.js';
let result = Add(1,2,3,4,5);
console.log(result); //15
</script>
(2)导入模块中的类:
module4.js
// class Student
// {
// constructor(stuno,stuname)
// {
// this.stuno = stuno;
// this.stuname = stuname;
// }
// sayHi()
// {
// console.log("大家好,我是"+this.stuname+",我的学号是"+this.stuno);
// }
// }
// export {Student};
//或
export class Student
{
constructor(stuno,stuname)
{
this.stuno = stuno;
this.stuname = stuname;
}
sayHi()
{
console.log("大家好,我是"+this.stuname+",我的学号是"+this.stuno);
}
}
HTML
<script type="module">
//导入类
import {Student} from './export/module4.js';
let stu = new Student("001","孙悟空");
stu.sayHi();
</script>
五、import的特点
module5.js
let name = "孙悟空";
let sex = "男";
let emp = {name:"孙悟空",sex:"男"};
export {name,sex,emp};
HTML
<script type="module">
//只读特点
//import {name,sex,emp} from './export/module5.js';
//(1)普通类型的值不能改变
// name = "猪八戒"; //报错
// sex = "男";//报错
//(2)不能直接改变对象
//emp = {name:"猪八戒",sex:"男"};
//(3)可以改变变量的属性值
// emp.name = "猪八戒";
// emp.sex = "男";
//单例特点
//(1)下面两句import只会执行一次
//import {name,sex,emp} from './export/module5.js';
//import {name,sex,emp} from './export/module5.js';
//(2)下面两句import相当于 import {name,sex} from './export/module5.js';
// import {name} from './export/module5.js';
// import {sex} from './export/module5.js';
//静态特点
//(1)不支持表达式
//import {"na"+"me"} from './export/module5.js'; //报错
//(2)不支持动态导入,以下代码也会报错
// if(true)
// import {name,sex} from './export/module5.js';
// else
// import {emp} from './export/module5.js';
</script>
六、模块的整体import加载
module5.js
let name = "孙悟空";
let sex = "男";
let emp = {name:"孙悟空",sex:"男"};
export {name,sex,emp};
HTML
<script type="module">
//加载module5中所有暴露出来的内容
import * as test from './export/module5.js';
console.log(test.name);
console.log(test.emp.name);
</script>
七、export default命令
使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载,export default 向外暴露的
成员,可以使用任意变量来接收,解决上述问题。
export default 命令特点:
(1)在一个文件或模块中,export、import 可以有多个,export default 仅有一个。
(2)export default 中的 default 是对应的导出接口变量。
(3)导入导出不需要{}符号。
(4)export default 向外暴露的成员,可以使用任意变量来接收。
(1)export default导出变量
module6.js
//export default导出变量不需要var
//export var a = 10; // 正确
// 正确
var a = 10;
export default a;
// 错误
//export default var a = 10;
HTML
<script type="module">
//接受默认变量
import b from './export/module6.js'; //此处可以用任意变量(b)来接受
console.log(b);
</script>
(2)export default导出函数
module6.js
function Add(...items)
{
let sum = 0;
for(let item of items)
{
sum += item;
}
return sum;
}
//此处Add不需要{}
export default Add
HTML
<script type="module">
//接受默认函数
import sum from './export/module6.js'; //此处可以用任意变量(sum)来接受
let result = sum(1,2,3,4,5);
console.log(result);
</script>
八、export与import的复合写法
export 与 import 可以在同一模块使用,我们称为复合使用。
(1)复合使用的基本语法
module1.js
// export let name = "孙悟空";
// export let sex = "男";
//或
let name = "孙悟空";
let sex = "男";
export {name,sex};
module7.js
//复合使用的语法
let emp = {name:"猪八戒",sex:"男"};
export { name, sex } from './module1.js';
// //上面的export等于如下:
// // import { name, sex } from './module1.js';
// // export { name, sex };
export {emp}
HTML
<script type="module">
//导入module7,在module7中导出module1内容
import {name,sex,emp} from "./export/module7.js";
console.log(name);
console.log(emp.name);
</script>
(2)复合写法实现接口改名
module1.js
// export let name = "孙悟空";
// export let sex = "男";
//或
let name = "孙悟空";
let sex = "男";
export {name,sex};
module7.js
//复合写法实现接口改名
let emp = {name:"猪八戒",sex:"男"};
export { name as myname, sex as mysex } from './module1.js';
export {emp}
HTML
<script type="module">
//导入改名后的变量
// import {myname,mysex,emp} from "./export/module7.js";
// console.log(myname);
// console.log(emp.name);
</script>
(3)转换为默认接口
module1.js
// export let name = "孙悟空";
// export let sex = "男";
//或
let name = "孙悟空";
let sex = "男";
export {name,sex};
module7.js
// 转换为默认接口
let emp = {name:"猪八戒",sex:"男"};
export {name as default,sex} from './module1.js';
export {emp}
HTML
<script type="module">
//导入修改成默认接口的name,使用abc接收
import abc from "./export/module7.js";
import {sex,emp} from "./export/module7.js";
console.log(abc);
console.log(emp.name);
</script>
(4)默认接口转换为命名接口
module6.js
function Add(...items)
{
let sum = 0;
for(let item of items)
{
sum += item;
}
return sum;
}
//此处Add不需要{}
export default Add
module7.js
//将默认接口转换为命名接口
export {default as sum} from './module6.js';
HTML
<script type="module">
//导入默认接口转换成的sum接口
import {sum} from "./export/module7.js";
let result = sum(1,2,3,4,5);
console.log(result);
</script>
(5)导出所有接口
module1.js
// export let name = "孙悟空";
// export let sex = "男";
//或
let name = "孙悟空";
let sex = "男";
export {name,sex};
module7.js
//导出所有
export * from './module1.js'
HTML
<script type="module">
//接收导出的所有接口
import {name,sex} from "./export/module7.js";
console.log(name);
console.log(sex);
</script>