在es6以前js没有关于模块化的管理方式,只有社区提供的commonjs和amd两种解决方案,在es6推出后在语法层面支持了模块化指令,分别是import
和export
两个指令用来加载和导出模块。
export 指令
export
指令,用于对外定义模块的对外接口,es6中,模块是一个独立的文件,模块内的变量是私有的,外部无法直接访问,当我们需要访问模块内的函数或变量时,就需要export
指令来帮我们规定那些操作是可以对外暴露进行访问的。
// db.js
export const url = 'www.baidu.com'
export const name = 'admin'
export const pwd = '123456'
上面是一个名为db.js
的模块,里面定义了关于db的信息并将信息导出供其他模块访问使用。这是export
的最基本形式,此外还可以简写为:
const url = 'www.baidu.com'
const name = 'admin'
const pwd = '123456'
export {url,name,pwd}
后一种写法是将要导出的信息统一进行导出,与前一种写法完全等价,但在可读性上要优于前一种,所以更推荐这种写法,同时export
不仅限于导出变量,也可以导出函数
export function foo(){
// do somthing
}
同时导出变量与函数
const a = 1
function foo(){
// do somthing
}
export {a,foo}
export支持使用别名的方式导出
const a = 1
function foo(){
// do somthing
}
export {a as b,foo as f}
此时导出变量和函数分别可以使用 b
和 f
进行访问
注意!!!
export
不能的导出必须是接口,必须与内部变量做对应关系,也就是说不能导出字面值
//报错
export 1
//报错
var a = 1
export a
1
是一个字面值,不能当做接口,也没有对应关系,所以会报错
a
指向的是a
,所以等价于前一种所以其实还是1
,所以报错
这种情况需要改写一下变成
export var a = 1
var a = 1
export {a}
import指令
import
指令用于导入一个模块到当前模块内使用。
import {url,name,pwd} from 'db.js'
export
导出了几个变量,在import
中就可以使用相同的变量名导入进来并使用。
import
同样支持别名,用法于export
相同
import {url as uri,name,pwd} from 'db.js'
import
导入的变量是只读的,且只加载执行一次,重复使用也只会加载一次
import {url,name,pwd} from 'db.js'
import {url,name,pwd} from 'db.js'
//只执行一次
虽然是只读的事实上对象只要引用没有变属性是可以改变的,但不推荐更改,当做只读就好
import
指令具有提升优化,不论定义在哪里都会提升到模块头部优先执行
foo()
import foo from 'function.js'
上面的代码是可以正常使用的。
import
虽然具有提升效果,但是必须定义在顶级作用域,不能定义在代码的执行阶段中,原因是import
是静态执行的,而代码块中的内容是运行时执行
定义太多接口时,import
支持使用*
来全部导入
import * as util from 'util.js'
util.isArray() //util.js中导出的接口
export default 指令
由于导入时需要知道全部的接口定义信息,很不方便,所以es6提供了更简单的default
方式来导出接口。
export default function foo(){
//do somthing
}
default
的意义在于为export
指令添加一个默认的输出,所有的接口都被输入到名为default
的变量中,所以在与普通export
的使用上会存在一些差异
export 1 //报错 1是字面值,不是接口,没后对应关系
export default 1 //通过 1被输入到default变量中,是接口,存在对应关系
export var a = 1//通过,创建一个值为1的变量,是接口,存在对应关系
export default var a = 1 //报错 已经存在default变量
var a = 1
export default a//通过 把a复制给default
import
在导入export default
的模块时,不需要书写全部的接口,可以使用任意名字进行命名。
import()
由于import
指令是静态执行,所以不能写在代码块里,导致不能在运行时动态的按需加载一些模块,导致不必要的浪费,所以es6中额外提供了一个函数来解决这个问题。
import()
函数的使用情景
//按需加载某些模块
const main = document.querySelector('main');
import(`./xx.js`)
.then(module => {
module.loadPageInto(main);
})
.catch(err => {
main.textContent = err.message;
});
import()
可以写在任何地方,函数会返回一个promise
对象在加载完成后,模块导出的接口会被当做参数传入到then()
函数
有点类似于
require()
的使用