详解ES6 模块化
本文我们学习ES6模块化,如何从模块中导出变量、函数、类并在其他模块中重用。
ES6 模块即为在严格模式下执行的JavaScript文件。意味着模块中声明的变量和函数不会自动增加至全局作用域中。
1. 浏览器中执行模块
首先创建新文件message.js并增加下列代码:
export let message = 'ES6 Modules';
在es6中message.js是一个模块,包含message变量。export语句暴露message变量给其他模块。
其次,创建新的文件app.js使用message.js模块。app.js模块创建h1元素并添加至html页中。import语句从message.js模块中导入message变量。
import { message } from './message.js'
const h1 = document.createElement('h1');
h1.textContent = message
document.body.appendChild(h1)
第三步,创建新的html页面文件使用app.js模块:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ES6 Modules</title>
</head>
<body>
<script type="module" src="./app.js"></script>
</body>
</html>
注意在script标签中加载type=“module”,如果在浏览器中打开该页面,下面信息:
ES6 Modules
下面我们详细讲解导入和导出语句。
2.Es6模块化
2.1 导出
要导出变量、函数或类,需要在其前面加export关键字:
// log.js
export let message = 'Hi';
export function getMessage() {
return message;
}
export function setMessage(msg) {
message = msg;
}
export class Logger {
}
log.js模块中有一个变量、两个函数和一个类,我们使用export关键字导出模块中所有标识符。
注意export关键字需要函数或类有名称,不能导出匿名函数或类。
JavaScript也支持先定义变量、函数或类,再导出:
// foo.js
function foo() {
console.log('foo');
}
function bar() {
console.log('bar');
}
export foo;
上例首先定义for函数然后导出。因为没有导出bar函数,其他模块不能访问该,对其他模块来说其是私有的不能访问。
2.2 导入
一旦在模块中使用export导出外部能访问的变量、函数或类,其他模块使用import关键字进行引入,语法如下:
import { what, ever } from './other_module.js';
- 使用花括号指定导入内容,称为绑定
- 指定从哪个模块导入绑定
注意当从模块中导入绑定时,绑定行为与const关键字定义类似。意味着不能其他标识符与之同名或修改绑定的值。
请看示例:
// greeting.js
export let message = 'Hi';
export function setMessage(msg) {
message = msg;
}
当导入message变量和setMessage函数,可以使用setMessa函数去改变message的值:
// app.js
import {message, setMessage } from './greeting.js';
console.log(message); // 'Hi'
setMessage('Hello');
console.log(message); // 'Hello'
但不能直接改变变量message的值,下面语句编译错误:
1
message = 'Hallo'; // error
实际你调用setMessage函数时,JavaScript回到greeting.js模块中执行代码修改message变量值,其他改变自动反应至导入的绑定变量message。
在app.js中的绑定变量message是局部变量,因此在两个模块中的message并不相同。
- 导入单个绑定
假如模块中有foo变量如下:
// foo.js
export foo = 10;
另一个模块能使用foo变量:
// app.js
import { foo } from './foo.js';
console.log(foo); // 10;
然而,你不能改变foo的值,如果修改则编译错误:
foo = 20; // throws an error
- 导入多个绑定
定义cal.js模块:
// cal.js
export let a = 10,
b = 20,
result = 0;
export function sum() {
result = a + b;
return result;
}
export function multiply() {
result = a * b;
return result;
}
你想从cal.js模块中导入这些绑定,可以显示列举:
import {a, b, result, sum, multiply } from './cal.js';
sum();
console.log(result); // 30
multiply();
console.log(result); // 200
- 导入全部模块作为对象
使用型号可以导入模块所有内容作为单个对象:
import * as cal from './cal.js';
示例中从cal.js模块中导入所有绑定作为单个对象,则所有绑定作为cal对象属性,访问示例:
cal.a;
cal.b;
cal.sum();
这个导入也称为命名空间导入。
特别需要注意的是import语句即使使用多次仅执行一次,示例:
import { a } from './cal.js';
import { b } from './cal.js';
import {result} from './cal.js';
第一个import语句之后,cal.js语句已执行并加载至内存,后续import语句会重用已载入内容。
2.3. import和export限制
注意import和export语句必须在其他语句和函数的外面。下面语句编译错误:
if( requiredSum ) {
export sum;
}
同样下面语句也错误:
function importSum() {
import {sum} from './cal.js';
}
因为两者都在其他语句之内。
2.4. 别名
JavaScript允许在导入或导出时创建别名。下面math.js模块:
// math.js
function add( a, b ) {
return a + b;
}
export { add as sum };
在导出时add使用as关键字增加别名为sum。
因此在导入add函数时必须使用sum代替:
import { sum } from './math.js';
在导入时也可以使用as关键字指定别名:
import {sum as total} from './math.js';
2.5. 重新导出绑定
也可以对导入绑定重新导出:
import { sum } from './math.js';
export { sum };
在示例从math.js模块导入sum,然后再重新导出。等价语句为:
export {sum} from './math.js';
在重新导出之前需重新命名绑定可使用as关键字。请看下面示例:
export { sum as add } from './math.js';
也可以导出其他模块所有绑定,使用星号:
export * from './cal.js';
2.6. 无绑定导入
有时你想开发不导出任何内容的模块,举例给内置Array对象增加新的方法:
// array.js
if (!Array.prototype.contain) {
Array.prototype.contain = function(e) {
// contain implementation
// ...
}
}
现在可以导入该模块,无需任何绑定并使用contain()方法:
import './array.js';
[1,2,3].contain(2); // true
2.7. 缺省导出
模块有仅只有一个缺省导出。缺省导出方便导入使用。模块缺省导出可以使用变量、函数或类,下面是sort.js模块的缺省导出:
// sort.js
export default function(arr) {
// sorting here
}
注意无需给函数指定名称,默认使用模块名称作为函数名称。
import sort from sort.js;
sort([2,1,3]);
你看到sort表示表示sort.js模块的缺省函数,我们不能对sort标识符使用{}。
下面修改sort.js模块增加非缺省函数:
// sort.js
export default function(arr) {
// sorting here
}
export function heapSort(arr) {
// heapsort
}
导入两个绑定可以使用绑定列表,规则如下:
- 确定绑定必须在首位
- 非缺省绑定必须使用花括号
import sort, {heapSort} from './sort.js';
sort([2,1,3]);
heapSort([3,1,2]);
从命名缺省导出可以使用as关键字:
import { default as quicksort, heapSort} from './sort.js';
3. 总结
本文我们学习ES6模块,如何从模块中导出绑定以及在其他模块中引入。
来源:CSDN
作者:neweastsun
链接:https://blog.csdn.net/neweastsun/article/details/104060748