一、ES6 模块化
概述:
ES6之前社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。
ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。
ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。
export命令:
export命令用于规定模块的对外接口
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。
如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。
export命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,这是因为处于条件代码块之中,就没法做静态优化了,违背了 ES6 模块的设计初衷。
const m = 1
export { m }
export { m as data }
export const n = 3
export function f() {}
function fn() {}
export {fn}
import命令:
import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块对外接口的名称相同。
如果import {b} from './b' 如果b中没有导出b变量,那么模块就会报错syntaxError。
并且引入的数据不能修改,如果修改了,会报错Syntax Error : 'a' is read-only。
但是可以修改对象属性如:a.b = 1,但是这会影响其他地方的引用,不建议采用此种书写方式。
import命令具有提升效果,会提升到整个模块的头部,首先执行。
import { a, b } from './test.js'
import { c as fn } from './test.js'
import { default as fn2 } from './test.js'
a = 'hello' // Syntax Error : 'a' is read-only
a.xxx = 'hello' // 可以修改,但是不推荐
// 由于import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。
let module = 'my_module';
import { foo } from module;