ES6模块化的概述
模块功能主要由两个命令构成:export
和import
。export
命令用于规定模块的对外接口,import
命令用于输入其他模块提供的功能,这种加载称为“编译时加载”或者静态加载,即ES6
可以在编译时就完成模块加载。
export命令
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export
关键字输出该变量
export导出变量的两种形式
- 分别暴露
// user.js
export var userName = 'xxx'
export var password = '123456'
export var age = 24
- 统一暴露
推荐使用这种写法,这样可以在模块底部,清晰的看到输出了哪些变量
// user.js
var userName = 'xxx'
var password = '123456'
var age = 24
export { userName, password, age }
export导出时使用 as 关键字重命名
// validate.js
function fn1 () {}
function fn2 () {}
export {
fn1 as validaName,
fn2 as validaPasswd,
}
export导出的注意点
export
命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系
// 错误写法
export 1; // 编辑器报错: 因为直接输出1
var m = 1;
export m; // 编辑器报错: 通过变量m 还是直接输出1, 1不是接口
以上两种写法都会报错,第一种直接输出1;第二种通过变量m,还是直接输出1,1不是接口,无法满足规定;函数和类也是如此。
// 正确写法
// 写法一
export var m = 1;
// 写法二
var m = 1;
export { m }
// 写法三
var m = 1;
export {m as n}
export
命令可以出现在模块的任何位置,只要处于模块顶层就可以,但是不能放在块级作用域内
// user.js
// 正确
var userName = 'xxx'
export var password = '12346'
var age = 24
export { userName, age }
// 错误
function check() {
export var password = '12346' // 处于块级作用域
}
export default命令
export default
命令用于指定模块的默认输出,一个模块只能有一个默认输出,因此export default
命令只能使用一次。使用as
重定义为default
也算使用,同样会报错。
// user.js
export default {
userName: 'xxx',
password: '123456',
age: 24
}
// import 导入
import userInfo from "./user.js"
console.log(userInfo)
// {
// age: 24
// password: "123456"
// userName: "xxx"
// }
export default
就是输出一个叫做default
的变量或方法,然后系统允许你为它取任意名字
// func.js
function add (x, y) {
return x + y
}
export { add as default }
// import 引入
import Add from "./func.js"
console.log(Add(1, 2)) // success 3
export default
命令其实只是输出一个叫做default
的变量,所以它后面不能跟变量声明语句
export default 2 // success 将2赋值给了default变量
export default var num = 2 // error
import命令
使用export
命令定义了模块的对外接口以后,其他JS
文件就可以通过import
命令加载这个模块
import + export 导出变量
- 通用导入/整体加载
// user.js 导出模块
var userName = 'xxx'
var password = '123456'
var age = 24
var dance = function () {
console.log('我可以跳舞')
}
export { userName, password, age, dance }
// import 导入
import * as userInfo from "./user.js"
console.log(userInfo)
// {
// userName: 'xxx',
// password: '123456',
// age: 24,
// dance: function () {
// console.log('我可以跳舞')
// }
// }
- 解构赋值的形式
import
命令可以使用as
关键字,将输入的变量重命名,解决变量命名冲突的问题
// user.js 导出模块
var userName = 'xxx'
var password = '123456'
var age = 24
var dance = function () {
console.log('我可以跳舞')
}
export { userName, password, age, dance }
// import 导入
import { userName, password, age, dance as fn1} from "./user.js"
console.log(userName) // 'xxx'
console.log(password) // '123456'
console.log(age) // 24
fn1() // '我可以跳舞'
import + export default 导出变量
// user.js
var obj = {
userName: 'xxx',
password: '123456',
age: 24
}
export default obj
- 通用导入/整体加载
整体加载时需要注意,使用
export default
默认导出,会多一层对象,对象的default
变量值才是导出的内容
import * as UserInfo from "../javascript/user.js"
console.log(UserInfo.default) // success obj
- 解构赋值的形式
解构赋值时需要注意,默认的导出变量是
default
,可以使用as
命令,对其重命名
import { default as UserInfo } from "../javascript/user.js"
console.log(UserInfo) // // success obj
- 简易形式
export default
独有
对于默认导出的内容,可以直接定义一个变量来接受,不用进行任何操作
import UserInfo from "../javascript/user.js"
console.log(UserInfo) // // success obj
import导入变量的注意点
import
命令输入的变量都是只读的,不允许在加载模块的脚本里面,改变导入的变量
如果导入的变量是引用类型的变量,那么可以修改对象属性,或者修改数组的元素
建议凡是输入的变量,都当作完全只读,不要轻易改变它的属性
import {a} from './user.js'
a = {}; // Syntax Error : 'a' is read-only;
import { obj, arr } from "./user.js"
obj.a = '123' // success
arr[1] = '111' // success
import
命令具有提升效果,会提升到到整个模块的顶部,但是不能写在块级作用域下
// success
foo()
import { foo } from "./user.js"
// error
if (sign === 1) {
import { foo } from "./user.js"
} else {
import { bar } from "./user.js"
}
import
是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构
// import 表达式 error
import { 'f' + 'oo' } from 'my_module';
// import 变量 error
var module = "./user.js"
import { foo } from module
- 一个模块可以有多个
export
语句和一个export default
语句,接受时,分开来接受即可
// user.js
export default add(x, y) {
return x + y
}
export var user = {
userName: 'xxx'
}
// import 导入
import Add from "./user.js"
import { user } from "./user.js"
Add(1, 2) // 3
console.log(user.userName) // xxx
export与import的复合写法
- 先输入后输出同一个模块
export { foo, bar } from "./user.js"
// 等同于
import { foo, bar } from "./user.js"
export { foo, bar }
- 接口改名
export { foo as myFoo } from "./user.js"
// 等同于
import { foo } from "./user.js"
export { foo as bar }
- 整体输出
此模式下,被引入模块的
export default
导出会被过滤掉
export * from "./user.js"
// 等同于
import * as user from "./user.js"
export user
- 具名接口改为默认接口
export { es6 as default } from './someModule';
// 等同于
import { es6 } from './someModule';
export default es6;
- 默认接口改为具名接口
export { default as es6 } from './someModule';
// 等同于
import es6 from './someModule';
export es6;