require和import的区别

简单比较

对比表格如下

对比类型 import require
何时加载 编译时加载 运行时加载
静态化 ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量 只有运行时才能得到这个对象,不能在编译时做到静态化
调用时间 import 是编译时调用,所以严格模式必须放在文件开头 require 是运行时调用,所以 require 理论上可以运用在代码的任何地方
模块输出 模块输出的是值的引用,不会缓存,而是动态地去被加载的模块取值,并且变量总是绑定其所在的模块 模块输出的是一个值的拷贝,并且在第一次加载是缓存,后面加载都会读取缓存
模块加载 按引入加载 整体加载
循环加载 ES6 模块是动态引用,如果使用 import 从一个模块加载变量,那些变量不会被缓存,而是成为一个指向被加载模块的引用,需要开发者自己保证,真正取值的时候能够取到值 CommonJS 模块的重要特性是加载时执行,即脚本代码在 require 的时候,就会全部执行。一旦出现某个模块被”循环加载”,就只输出已经执行的部分,还未执行的部分不会输出

下面我们一项一项具体解释:

何时加载/静态化

require / exports :
遵循 CommonJS/AMD,只能在运行时确定模块的依赖关系及输入/输出的变量,无法进行静态优化

import / export:
遵循 ES6 规范,支持编译时静态分析,便于 JS 引入宏和类型检验。动态绑定

调用时间

import / export:
import 命令具有提升效果,会提升到整个模块的头部,首先执行。(是在编译阶段执行的)
因为 import 是静态执行的,不能使用表达式和变量,即在运行时才能拿到结果的语法结构.

require / exports :
require 是运行时调用,所以 require 理论上可以运用在代码的任何地方

模块输出/模块加载

require / exports :
CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值,并且会在第一次加载是缓存这个值的拷贝,他是完全输出这个值的拷贝。

import / export:
模块输出的是值的引用不会缓存,而是动态地去被加载的模块取值,并且变量总是绑定其所在的模块,并且只会加载引入的值,不去全部加载。