前言:
ES6(也称为ES2015)和CommonJS都是JavaScript的模块系统,但它们有一些关键的区别。ES6是最新的ECMAScript标准,被现代浏览器广泛支持,并且也可以通过Babel等编译工具转换为ES5来在旧版浏览器中运行。CommonJS是一种用于服务器端的模块规范,是Node.js默认的模块系统。
1. 语法差异:
ES6模块使用`import`和`export`关键字进行导入和导出,顶层的变量和函数都是默认导出的。而CommonJS使用`require()`函数引入模块,`module.exports`和`exports`关键字用于导出模块。ES6模块的导入和导出都是静态的,在编译时就确定了,而CommonJS模块的导入和导出是动态的,在运行时才确定。
// ES6模块导入和导出示例
// 导入
import { foo } from './module';
// 导出
export default function bar() {
console.log('Hello, ES6 module!');
}
// CommonJS模块导入和导出示例
// 导入
const { foo } = require('./module');
// 导出
module.exports = function bar() {
console.log('Hello, CommonJS module!');
};
2. 模块加载方式:
ES6模块是异步加载的,可以使用`import()`动态地加载模块。这是因为ES6模块的设计目标是在浏览器中运行,而浏览器中的模块加载是基于网络的,因此需要异步加载的能力。CommonJS模块是同步加载的,只有当所有的依赖模块都加载完毕后,才会执行模块的代码。
// ES6模块动态加载示例
import('./module')
.then(module => {
const { foo } = module;
// ...
})
.catch(error => {
console.error('Failed to load module', error);
});
// CommonJS模块同步加载示例
const { foo } = require('./module');
// ...
3. 模块作用域:
ES6模块的顶层作用域是模块级的,每个模块都有自己的作用域,模块内部的变量和函数默认都是私有的,只能在模块内部访问。需要明确导出的变量和函数才能被其他模块所引用。CommonJS模块的顶层作用域是文件级的,模块中定义的变量和函数都属于该文件的全局作用域,它们可以被该模块内的其他函数和其他模块所引用。
// ES6模块作用域示例
// module.js
const foo = 123;
export function getFoo() {
return foo;
}
// main.js
import { getFoo } from './module';
console.log(getFoo()); // Output: 123
// CommonJS模块作用域示例
// module.js
const foo = 123;
function getFoo() {
return foo;
}
exports.getFoo = getFoo;
// main.js
const { getFoo } = require('./module');
console.log(getFoo()); // Output: 123
总结:
ES6和CommonJS都是JavaScript的模块系统,但在语法、模块加载方式和模块作用域等方面存在一些区别。ES6模块使用import和export关键字实现导入和导出,是静态的、异步加载的,拥有模块级的作用域;而CommonJS使用require()函数和exports/module.exports关键字实现导入和导出,是动态的、同步加载的,拥有文件级的作用域。了解这些区别有助于我们在开发过程中选择合适的模块系统来满足不同的需求。