ES6中import和export引出的问题

148 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情

导入

在现在的vue项目中,import和export随处可见,每次都是复制出来一个,就OK。但是到底是怎么回事呢?

export

export命令用于规定模块,对外提供的接口

export命令可以导出变量、函数和class类

错误的示范

 // 报错
 export 1;
 ​
 // 报错
 var m = 1;
 export m;
 ​
 // 报错
 function f() {}
 export f;

因为没有提供对外的接口。第一种写法直接输出 1,第二种写法通过变量m,还是直接输出 1。1只是一个值,不是接口。正确的写法是下面这样。

正确的操作

 // 写法一
 export var m = 1;
 ​
 // 写法二
 var m = 1;
 export {m};
 ​
 // 写法三
 var n = 1;
 export {n as m};
 ​
 // 正确
 export function f() {};
 ​
 // 正确
 function f() {}
 export {f};

上面三种写法都是正确的,规定了对外的接口m。其他脚本可以通过这个接口,取到值1。它们的实质是,在接口名与模块内部变量之间,建立了一一对应的关系。

使用大括号指定所要输出的一组变量。与前一种写法(直接放置在var语句前)是等价的,但是应该优先考虑使用这种写法。因为这样就可以在脚本尾部,一眼看清楚输出了哪些变量。

import

使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。

 // main.js
 import { firstName, lastName, year } from './profile.js';
 ​
 // import { lastName as surname } from './profile.js';
 ​
 // firstName = '小华' 错误
 ​
 function setName(element) {
   element.textContent = firstName + ' ' + lastName;
 }
  1. 上面代码的import命令,用于加载profile.js文件,并从中输入变量。import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。
  2. 如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。
  3. import命令输入的变量都是只读的,因为它的本质是输入接口。不允许在加载模块的脚本里面,改写接口。如果导出的是一个对象,那我们去修改对象的属性是允许的。

export default

为模块默认输出

 // 第一组
 export default function crc32() { // 输出
   // ...
 }
 ​
 import crc32 from 'crc32'; // 输入
 ​
 // 第二组
 export function crc32() { // 输出
   // ...
 };
 ​
 import {crc32} from 'crc32'; // 输入
  1. 第一组是使用export default时,对应的import语句不需要使用大括号;第二组是不使用export default时,对应的import语句需要使用大括号。
  2. export default命令用于指定模块的默认输出。一个模块只能有一个默认输出,因此export default命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能唯一对应export default命令。
  3. 本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。

如果想在一条import语句中,同时输入默认方法和其他接口,可以写成下面这样。

 import _, { each, forEach } from 'lodash';

export 与 import 的复合用法

如果在一个模块之中,先输入后输出同一个模块,import语句可以与export语句写在一起。

 export { foo, bar } from 'my_module';
 ​
 // 可以简单理解为
 import { foo, bar } from 'my_module';
 export { foo, bar };

总结

以上都是ESM模块化,提供的方法。既然提到了模块化,那就有其他的AMD、CMD、Common.js[CJS]。他们是怎么一步步演变的呢?还有就是浏览器是怎么加载的呢?它的运行机制是什么呢?