require和import的区别

162 阅读2分钟
  • 对应的规范不同,require对应commonjs规范,import对应esm规范

require

  • require 是在运行时加载
  • 对于基本数据类型,属于复制。即会被模块缓存。同时,在另一个模块可以对该模块输出的变量重新赋值
  • 对于复杂数据类型,属于浅拷贝。由于两个模块引用的对象指向同一个内存空间,因此对该模块的值做修改时会影响另一个模块
  • 出现模块之间的循环引用时,会输出已经执行的模块,而未执行的模块不输出(比较复杂)
// b.js
exports.done = false
let a = require('./a.js')
console.log('b.js-1', a.done)
exports.done = true
console.log('b.js-2', '执行完毕')

// a.js
exports.done = false
let b = require('./b.js')
console.log('a.js-1', b.done)
exports.done = true
console.log('a.js-2', '执行完毕')

// c.js
let a = require('./a.js')
let b = require('./b.js')

console.log('c.js-1', '执行完毕', a.done, b.done)

node c.js
b.js-1 false
b.js-2 执行完毕
a.js-1 true
a.js-2 执行完毕
c.js-1 执行完毕 true true

  • CommonJS模块默认export的是一个对象,即使导出的是基础数据类型,也必须在对象内
  • require命令加载同一个模块时,不会再执行该模块,而是取到缓存之中的值。也就是说,CommonJS模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存

import

  • import 是在编译时加载,可用于静态分析,属于值引用的方式
  • 不管是基础(复杂)数据类型,都只是对该变量的动态只读引用。动态在于一个模块中变量的变化会影响到另一个模块;只读在于从某个模块引入一个变量时,不允许修改该变量的值。对于复杂数据类型,可以添加属性和方法,但是不允许指向另一个内存空间。
  • 出现模块之间的循环引用时,只要模块存在某个引用,代码就能够执行。