-
import 、export 命令
export 命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
处理 import /export 语句是在编译时,所以 import 和 export 命令只能在模块的顶层,不能在代码块中。
require 是运行时加载模块,import 命令无法取代 require 的动态加载功能。
-
export 命令
一个模块就是一个独立的文件,该文件内部的所有变量,外部无法获取。若要使用模块内部的某个变量,就必须使用 export 关键字输出该变量。
export 命令可以出现在模块的任何位置,只要处于模块顶层就可以。
(1)export命令后,使用大括号指定所要输出的一组变量(推荐)/ 直接跟此变量输出。
通常情况下,export 输出的变量就是本来的名字,但可以用 as 关键字重命名。
// profile.js // profile.js
var firstName = 'Michael'; export var firstName = 'Michael';
var lastName = 'Jackson'; export var lastName = 'Jackson';
var year = 1958; export var year = 1958;
export { firstName, lastName, year };
//export 输出函数或者类,可以使用 as 进行重命名
function v1() { ... }
function v2() { ... }
// 可以用 as 关键字进行重命名
export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVersion
};
(2)export default 命令为模块指定默认输出。其他模块加载该模块时, import 命令可以为该匿名函数指定任意名字(此时不需要大括号)。一个模块只能有一个默认输出。
export default
命令其实只是输出一个叫做default
的变量,所以它后面不能跟变量声明语句。
//export-default.js
export default function () {
console.log('foo');
}
//import-default.js
//import 命令可以为该匿名函数指定任意名字。import 命令后不需要大括号。
import customName from './export-default.js';
customName() ; //foo
(4)export 语句输出的接口,与其对应的值是动态绑定关系。即通过该接口,可以取到模块内部实时的值。
-
import 命令
(1)import 命令接受一对大括号,里面指定从其他模块导入的变量名。大括号里面的变量名必须与被导入模块对外接口名称相同。
import 命令可以使用 as 关键字,将输入的变量重命名。
(2)import 命令后面的 from 指定模块文件的位置,可以是相对路径,也可以是绝对路径。.js 后缀可以省略。
(3)import 命令输入的变量是只读的,不允许在加载模块的脚本里面,改写接口。
(4)import 命令具有提升效果,会提升到整个模块的头部,首先执行。
(5)import 命令是编译阶段执行的,静态执行,不能使用表达式和变量。
(6)import 命令语句会执行所加载的模块,如果多次重复执行同一句 import 语句,那么只会执行一次,而不会执行多次。
import {foo,bar} from './xxx.js'
import {foo as foo2} from './xxx.js'
(7)import 命令模块的整体加载,用 星号(*)指定一个对象,所有输出值都加载在这个对象上面。
注意: 模块的整体加载坐在的那个对象应该是可以静态分析的,不允许运行时改变。
//使用 * 号进行模块整体加载。但整体加载所在的那个对象(cicre) 是不允许运行时改变的。
import * as cicre from './a.js';
//下面两行是不允许的。
cicre .foo = 'hello';
cicre .area = function () {};
-
export 和 import 的复合写法
若在一个模块之中,先输入后输出同一个模块,import 语句可以与 export 语句写在一起。
需注意:在当前模块中使用 export和 import 的复合写法导入方法时,当前的模块实际上并没有导入该方法,只是相当于对外转发了这两个接口。所以当前模块是不能直接使用该方法的。
export { foo, bar } from 'my_module';
// 可以简单理解为
import { foo, bar } from 'my_module';
export { foo, bar };
/*上面代码中 export和import 语句结合在一起。但需注意,写成这种复合写法后
foo,bar 实际上并没有被导入当前的模块,只是相当于对外转发了这两个接口,导致当前模块不能直接使用
foo 和 bar。
**/
使用场景:
(1)接口改名
//接口改名
export {foo as myFoo} from 'my_module';
(2)整体输出
export * from 'my_module';
(3)具名接口改为默认接口,默认接口改名为具名接口
//默认接口写法如下:
export { default } from 'foo';
//具名接口改为默认接口
export { es6 as default } from './someModule';
// 等同于
import { es6 } from './someModule';
export default es6;
//默认接口改为具名接口
export { default as es6 } from './someModule';
(4)实现模块的继承
circleplus模块,继承了circle模块。
// circleplus.js
export * from 'circle';
export var e = 2.71828182846;
export default function(x) {
return Math.exp(x);
}
-
import() 函数,支持动态加载模块
import 命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行。import 命令是在编译时处理,导致 import 命令无法取代 require 的动态加载功能。引入 import() 函数,支持动态加载模块。
import() 函数可以用在任何地方,不仅仅是模块,非模块的脚本也可以使用。它是运行时执行。
import() 函数返回一个 Promise 对象。
import() 函数与所加载的模块没有静态连接关系,import() 类似于Node 的 require 方法,不同在于 :import 是异步加载,require 是同步加载
import() 适用场合:
(1)按需加载
button.addEventListener('click', event => {
import('./dialogBox.js')
.then(/*....*/)
.catch(error => { /* Error handling */ })
});
(2)条件加载,import() 可以放在 if 代码块,根据不同的情况,加载不同的模块。
if (condition) {
import('moduleA').then(...);
} else {
import('moduleB').then(...);
}
(3)动态的模块路径, import() 允许模块路径动态生成
import(f()).then(...);
import()注意点:
(1)import() 加载模块成功后,模块会作为一个对象当做 then() 方法的参数。可以使用对象解构赋值的语法,获取输出接口。
export1和export2都是myModule.js的输出接口,可以解构获得
import('./myModule.js').then(({export1, export2}) => {/**/});
(2)若模块中有 default输出接口,可以用参数直接获得。也可以使用具名输入的形式。
模块有default输出接口,可以用参数直接获得
import('./myModule.js').then(myModule => { console.log(myModule.default);});
也可以使用具名输入的形式。
import('./myModule.js').then(({default: theDefault}) => {
console.log(theDefault);
});
(3)同时加载多个模块
Promise.all([
import('./module1.js'),
import('./module2.js'),
import('./module3.js'),
])
.then(([module1, module2, module3]) => {/**/});
(4)import() 可以用在 async 函数中
async function main() {
const myModule = await import('./myModule.js');
const {export1, export2} = await import('./myModule.js');
const [module1, module2, module3] =
await Promise.all([
import('./module1.js'),
import('./module2.js'),
import('./module3.js'),
]);
}
main();
-
严格模式
-
跨模块常量