require和ES6-import的区别

9次阅读

共计 1239 个字符,预计需要花费 4 分钟才能阅读完成。

js 模块化的进程里,出现了很多模块化的方案,commonjs,requirejs(AMD),CMD。随着 ES6 标准的发布,import/export 的规范也被广泛使用了。只是浏览器的支持程度不高,需要配合转码工具使用。ES6 的模块化和之前社区的 commonjs 模块化到底有什么区别呢?

Commonjs 的 require 和 module.exports

  • require 是个函数,动态加载 ,也因此

1.require 导入是在运行时,理论上可以在任意地方调用 require 导入模块;
2.require() 的路径可以是表达式:require(‘/app’ + ‘/index’);

  • require 返回对应 module.exports 对象的浅拷贝

1. 如果是 module.exports 里的基本类型的值,会得到该值的副本
2. 如果是 module.exports 里的对象类型的值,会得到该值的引用

ES6 的 import 和 export

  • import 在编译时确定导入

1. 路径只能是字符串常量
2.import 会被提升到文件最顶部
3. 导入的变量是只读的

  • import 导入的是值引用,而不是值拷贝

1. 模块内部值发生变化,会对应影响到引用的地方
2.import 导入与导出需要有一一映射关系,类似解构赋值。

代码说明一下两者的区别

Commonjs

// a.js
let a = 0;
const count = () => {a++;}
setTimeout(function(){
    a++;
    console.log('in module the a is' + a);
}, 500);
module.exports = {
    a,
    count,
};

// b.js
let foo = require('a.js');
foo.count();
setTimeout(function(){console.log('in require the a is' + foo.a);
}, 1000);

// 输出
// in the module the a is 2
// in the require the a is 0

因为 foo 是一份浅拷贝,所以 a 是 require 导入时 export 里 a 的值;而 count 是一个函数,foo.count 是这个函数的一个引用,所以调用时作用域是它声明处一样,也就是它修改的 a 是 exports 里的,而不是 foo.a。

Es6 module

// a.js
let a = 0;
const count = () => {a++;}
setTimeout(function(){
    a++;
    console.log('in module the a is' + a);
}, 500);
export {
    a,
    count,
};

// b.js
import {a, count} from 'a.js';
count();
setTimeout(function(){console.log('in require the a is' + a);
}, 1000);

// 输出
// in the module the a is 2
// in the require the a is 2

可以看出,很重要的一个区别就是一个基本值是否会同步变化,

正文完
 0