- Notifications
You must be signed in to change notification settings - Fork0
Description
一、ES6模块体系简述
1、上一篇“ javascript模块化进程 ”中也说到:历史上,JavaScript 一直没有模块体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。ES6之前,社区制定了一些模块加载方案,最主要的有 CommonJS(服务器)和 AMD/CMD(浏览器)两种。
2、ES6在语言标准的层面上,实现了模块功能,完全可以取代 CommonJS 和 AMD(CMD) 规范,成为浏览器和服务器通用的模块解决方案。
二、ES6模块
1、ES6 模块与CommonJS 、 AMD 模块区别
ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
CommonJS 和 AMD 模块,都只能在运行时确定模块依赖关系(运行时加载),因为只有运行时才能得到模块对应的对象(如,CommonJS 模块就是对象,输入时必须查找对象属性)。
ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。
2、ES6 模块特性
一个模块就是一个独立的文件,其内部的所有变量,外部无法获取。
编译时加载或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。
ES6模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入,因此没法引用模块本身。
3、ES6模块构成的两个关键字
- export:规定模块的对外接口
- import:输入模块提供的功能
4、export关键字
A、输出变量、函数、类
// 直接输出export const name = 'jackxu';export const add = (x = 0, y = 0) => { return x + y;};export class Hello { sayHi() { console.log('Hi~!'); }}// 统一输出const name = 'jackxu';const add = (x = 0, y = 0) => { return x + y;};class Hello { sayHi() { console.log('Hi~!'); }}export { name, add, Hello }- B、输出的变量就是原变量名,可以使用as关键字重命名
const name = 'jackxu';const add = (x = 0, y = 0) => { return x + y;};class Hello { sayHi() { console.log('Hi~!'); }}export { name as ESName, add as addTwo, Hello as Hi}5、export使用注意事项
A、export规定模块的对外接口,必须与模块内部的变量建立一一对应的关系
// 错误写法const add = (x = 0, y = 0) => { return x + y;};export add;export 123;// 正确写法const add = (x = 0, y = 0) => { return x + y;};const A = 1;export { add, A }- B、export命令可以出现在模块的任何位置,但必须处于模块顶层
const fn = () => { export const a = 'bar';};fn();6、import关键字
A、加载模块提供的功能(输入模块提供的功能)
import { name, add, Hello } form '模块相对路径/模块绝对路径/模块文件名'模块后缀
.js可以省略,相对路径./不能省略
模块文件名,由于不带路径,必须进行配置(如webpack+nodejs路径配置)
如加载先前export输出变量:
// 加载多个变量import { name, add, Hello } form './class/test17';// 加载单个变量import { name } form './class/test17';- B、模块的整体加载:用星号 * 指定一个对象,所有输出值都加载在这个对象上面
import * as filters form '模块相对路径/模块绝对路径/模块文件名'如整体加载先前export输出变量:
import * as test form './class/test17';模块整体加载所在的那个对象(如上面test),应该是可以静态分析的,所以不允许运行时改变。
如修改先前export输出的函数add,虽然不会报错,但不应这么操作。
import * as test from './class/test17';test.cname = '李四'; // 不恰当写法test.add = () => 666; // 不恰当写法- C、import命令具有提升效果,会提升到整个模块的头部,首先执行。
如先执行add,在import输入export输出的变量add
console.log(add(2));import { add } from './class/test17';- D、import语句会执行所加载的模块,如果多次重复执行同一句import语句,那么只会执行一次,而不会执行多次。
import '../../assets/styles/collect.css' // 仅仅执行模块,但是不输入任何值- E、import是静态执行,所以不能使用表达式和变量(这些只有在运行时才能得到结果的语法结构)
如下使用变量和表达式的import操作都会报错:
import { 'n' + 'ame' } from './class/test17';let module = './class/test17';import { name } from module;const a = 1;a === 1 ? import { name } from './class/test17' : '';- 7、export default关键字
export输出的模块,import加载的时,需要知道加载的变量名、函数名或类名,否则无法加载。而实际业务中,很可能不知道具体变量名,这时候就需要使用export default关键字。
- A、export default输出的模块,使用import加载的时候,变量名可以任意指定名字,但import后面不使用
{}
// export default输出const name = 'jackxu';const add = (x = 0, y = 0) => { return x + y;};class Hello { sayHi() { console.log('Hi~!'); }}export default { name, add, Hello }// import 输入import test from './class/test17';console.log(test.name);console.log(test.add(3, 6));B、export default也可输出非匿名函数,系统默认函数名在模块外部无效,加载的时候视同匿名函数加载
匿名函数:
// export default输出export default (arr = []) => { return arr.filter(item => item > 6);}// import 输入import filterArr from './class/test17';console.log(filterArr([1, 4, 6, 8, 9, 10]));非匿名函数:
// export default输出export default function filter_arr(arr = []) { return arr.filter(item => item > 6);}// import 输入import filterArr from './class/test17';console.log(filterArr([1, 4, 6, 8, 9, 10]));- C、export default用于指定模块的默认输出,一个模块只能有一个默认输出,因此export default命令只能使用一次
const _A = 123, _B = (...arg) => new Map().set('arg', arg); export default _A;export default _B;- D、export default本质:输出一个名为default的变量或方法,然后系统允许为其任意取名
demo1:
// babel转码前export default () => { console.log('山穷水尽,柳暗花明');}// babel转码后'use strict';Object.defineProperty(exports, "__esModule", { value: true});exports.default = function () { console.log('山穷水尽,柳暗花明');};demo2:
// babel转码前const name = 'jackxu';const fn = () => 5;export default { name, fn };// babel转码后'use strict';Object.defineProperty(exports, "__esModule", { value: true});var name = 'jackxu';var fn = function fn() { return 5;};exports.default = { name: name, fn: fn };- E、export default其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句。
错误写法:
export default const _B = 123;正确写法:
const _B = 123;export default _B;// 对比exportexport const _B = 123;export default 66;// 对比exportexport 66; // 错误写法主要参考资料:






