小帅的编程笔记|全面理解ES6模块化编程
今天我们来学习ES6的模块化系统,如何从模块中导出变量、函数、类,在其他模块中去使用。
在ES6的模块系统中,每个JS文件可以理解为一个模块,模块代码以严格模式执行,所以模块中的变量、函数不会添加全局作用域中。
在ES6之前,我们可能需要使用require.js来实现模块化编程,在Node.js中使用commonjs规范来模块化编程,JS并没有一个统一的规范,所以在ES6推出了全新的模块化方案。
在浏览器中运行 创建一个文件 message.js
export let message = 'ES6 Modules';
message.js
是ES6中的一个模块,包含一个message
变量,使用 export
语句将message
变量暴露给其他模块。然后创建一个
app.js
,在app.js
中我们引入 message.js
模块,在app.js
中,我们创建一个h1元素并插入到页面中。import
语句用来从 message.js
模块导入 message
变量。import {
message } from './message.js'const h1 = document.createElement('h1');
h1.textContent = messagedocument.body.appendChild(h1)
最后,创建一个html文件,引入
app.js
ES6 Modules - 锐客网
type="module" src="https://www.it610.com/article/app.js">
注意:这里我们需要在script标签上加
type="module"
用来引入 app.js
模块。运行成功如下文章图片
注意:需要起个本地服务器来打开页面,不能直接使用本地打开文件方式。
export 导出 要从一个模块中导出一个变量、函数或者类,我们需要用到
export
关键字// log.js
export let message = 'Hi';
export function getMessage() {return message;
}export function setMessage(msg) {message = msg;
}export class Logger {}
在上面的例子中,我们创建了log.js这个模块,里面有1个变量,两个函数,1个类,然后我们使用
export
来导出它们。要注意的是,用export导出的函数或者类需要有名称,我们不能使用export导出匿名函数或者类。
我们也可以先定义变量或者函数,然后在后面再将其导出
// foo.js
function foo() {console.log('foo');
}function bar() {console.log('bar');
}
export foo;
在上面例子中,我们首先定义了foo函数,然后在后面将其导出,由于我们没有导出bar函数,所以在其他模块中是无法访问的,只能在当前模块中使用,我们可以称之为私有函数。
import 导入 有了带有导出的模块后,我们就可以使用
import
关键字去访问另一个模块中的变量、函数或者类import {
what, ever } from './other_module.js';
在花括号内指定要导入的变量、函数或者类名称。
注意:当我们导入模块时,就像是const定义变量一样,引入后
what
和ever
不允许再去更改。举个例子
// greeting.js
export let message = 'Hi';
export function setMessage(msg) {message = msg;
}
当我们引入message变量和setMessage()函数后,我们可以调用
setMessage()
函数去改变模块内message变量的值。// app.js
import {
message, setMessage } from './greeting.js';
console.log(message);
// 'Hi'setMessage('Hello');
console.log(message);
// 'Hello'
但如果直接去修改message变量,就会报错
message = 'Hallo';
// error
其实,当我们调用setMessage()函数时,JS会去到
greeting.js
模块中去执行代码并修改message变量,然后导入的message变量也会随着变化。import 导入多个变量/函数
在cal.js中导出a、b、result变量和sum()、multiply()函数
// 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;
}
接着在app.js中去引入,使用它们
// app.js
import {
a, b, result, sum, multiply } from './cal.js';
sum();
console.log(result);
// 30multiply();
console.log(result);
// 200
import导入整个模块作为对象
沿用上面的例子,我们可以使用
*
号关键字,将模块中的所有内容作为单个对象导入import * as cal from './cal.js';
然后可以使用cal对象去访问导出的变量和函数
cal.a;
cal.b;
cal.sum();
import
/ export
的限制 注意,import
/ export
语句只能在代码的最外层执行,不能在其他作用域内执行,下面的代码会报语法错误const a = 10
if(true) {export a;
}
同样下面的import语句也会报语法错误
function importSum() {import {
sum } from './cal.js';
}
产生错误的原因是,ES6的
import
/ export
只能通过静态方式确定导入或者导出的内容,无法动态引入模块。但在ES2020中引入了
import()
函数,可以支持动态导入模块。别名导出 /导入 下面我们将add()函数使用别名sum进行导出,我们使用
as
关键字,在后面写上要导出的别名// math.js
function add( a, b ) {return a + b;
}export {
add as sum };
然后在引入模块时,我们要使用引入add()时,我们要用sum去代替
import {
sum } from './math.js';
如果在导入时我们不想使用sum作为导入,我们也可以使用
as
关键字去使用其他名称import {
sum as total} from './math.js';
重新导出 重新导出导入的模块
import {
sum } from './math.js';
export {
sum };
下面这个语法等同于上面
export {
sum } from './math.js';
我们也可以使用别名进行重新导出
export {
sum as add } from './math.js';
重新导出所有,我们可以使用
*
号export * from './cal.js';
有的同学可能不知道这重新导出有什么作用,其实这作用还挺大的,比如我们写了20个组件,我们不想写20条import语句,只想写1条import语句,那么我们就可以建一个中间文件将这个20个组件引入,然后全部导出,然后我们在用的时候就一条import语句就好了,可以参考ant design的组件库的写法。
// 参考:https://github.com/vueComponent/ant-design-vue/blob/next/components/index.tsimport * as components from './components';
import {
default as version } from './version';
export * from './components';
匿名导入 有时,我们会开发一个不需要指定名称导入的模块,如果我们想给原生Array增加一个方法
// array.js
if (!Array.prototype.contain) {Array.prototype.contain = function(e) {// ...
}
}
接着,我们直接去import该模块,然后使用数组的contain方法
import './array.js';
[1,2,3].contain(2);
// true
默认导出 一个模块只能有一个默认导出,一般来说默认导出更容易被导入,因为我们不需要再去看导入的变量、函数或者类的名称就可以导入,一般来说一个模块若只有一个导出我们可以使用默认导出。
下面的
sort.js
模块默认导出一个函数// sort.js
export default function(arr) {// 给数组排序
}
使用
sort.js
模块import sort from './sort.js';
sort([2,1,3]);
引入的
sort
就相当于sort.js
模块中导出的默认函数。同样,在有默认导出的同时我们也可以导出其他函数
// sort.js
export default function(arr) {// 给数组排序
}
export function heapSort(arr) {// 堆排序
}
要从模块中导入默认导出和非默认导出我们要遵循下面的规则
- 首先,默认导出要在最前面
- 其他非默认导出,在后面用花括号导入
import sort, {
heapSort } from './sort.js';
sort([2,1,3]);
heapSort([3,1,2]);
如果要别名默认导出,我们也可以使用
as
关键字,像这样import {
default as quicksort, heapSort} from './sort.js';
总结 今天我们学习了JavaScript ES6模块化编程的方方面面,如果有问题欢迎留言评论。我们明天见。
【小帅的编程笔记|全面理解ES6模块化编程】如果本文有帮助,微信搜索【小帅的编程笔记】,让我们每天进步
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量