…
年末不算很忙,还是把拖了 N 月的 todo 整理了吧…总不能带到过年呀。O_O
前言
自我感觉,require/import 本身也是两个时代的产物,自我认知的区别性,规范不同,表达形式不同,出现时代不同,运行时期不同等。(以下 require 主要以 CommonJS 规范为例)
1 | // require |
规范不同
require/exports 并非官方规范,而是来之 CommonJS,(社区产物,当然除了 CommonJS(node) 还有 AMD(requirejs)、CMD(seajs) 等规范,CommonJS 作为 Nodejs 的规范,一直沿用至今)。
import/export 则是来之官方,遵循 ECMAScript 规范,由 ES6 开始引入。
时代不同
在 ES6 之前,JavaScript 不支持类(class),所以也没有模块(module)。但是社区是伟大的,出现了如 CommonJS 等第三方社区规范,Nodejs 的出现也标志着“JS 模块化编程”的诞生。
ES6 标准发布后,module 成为标准,标准使用是以 export 指令导出接口,以 import 引入模块,但是在 node 模块中,依然采用的是 CommonJS 规范,使用 require 引入模块,使用 module.exports 导出接口。
形式不同
require
1 | // a.js |
1 | // b.js |
import
1 | // a.js |
1 | // b.js |
当然还有*
as
等,更多用法可见->import-MDN
本质差别
将 import/export 使用 babel 转成 es5 可以看到明显差别:
1 | // es6 |
1 | // es5 |
当然以上差异产生的原因是因为要实现 import/export 的export default
。如果只是引用一个模块方法好像形式上也没什么区别:
1 | // es6 |
1 | // es5 |
我能感觉到的区别是,import是编译时加载,require是运行时加载。所以import只能在头部,而require相对宽松,甚至可以所为表达式使用。
- CommonJS 还是 ES6 Module 输出都可以看成是一个具备多个属性或者方法的对象;
- default 是 ES6 Module 所独有的关键字,export default fs 输出默认的接口对象,import fs from ‘fs’ 可直接导入这个对象;
- ES6 Module 中导入模块的属性或者方法是强绑定的,包括基础类型;而 CommonJS 则是普通的值传递或者引用传递。