前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么ES模块比CommonJS更好?

为什么ES模块比CommonJS更好?

作者头像
用户10106350
发布2022-10-28 11:23:54
6890
发布2022-10-28 11:23:54
举报
文章被收录于专栏:WflynnWeb

ES6 模块与 CommonJS 模块的差异

1.CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。2.CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。请看下面这个模块文件lib.js的例子。

代码语言:javascript
复制
// lib.js	
var counter = 3;	
function incCounter() {	
counter++;	
}	
module.exports = {	
counter: counter,	
incCounter: incCounter,	
};

上面代码输出内部变量counter和改写这个变量的内部方法incCounter。然后,在main.js里面加载这个模块。

代码语言:javascript
复制
// main.js	
var mod = require('./lib');	
	
console.log(mod.counter);  // 3	
mod.incCounter();	
console.log(mod.counter); // 3

上面代码说明,lib.js模块加载以后,它的内部变化就影响不到输出的mod.counter了。这是因为mod.counter是一个原始类型的值,会被缓存。除非写成一个函数,才能得到内部变动后的值。

ES6 模块的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。

换句话说,ES6 的import有点像 Unix 系统的“符号连接”,原始值变了,import加载的值也会跟着变。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块(动态绑定)。

第二个差异是因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。

代码语言:javascript
复制
// 不能这样写	
const flag = true	
if (flag) {	
import $ from 'jquery'	
}	
// 但是可以这样写	
if (flag) {	
const $ = require('jquery')	
}

为什么ES模块比CommonJS更好?

ES模块是官方标准,也是JavaScript语言明确的发展方向,而CommonJS模块是一种特殊的传统格式,在ES模块被提出之前做为暂时的解决方案。ES模块允许进行静态分析,从而实现像 tree-shaking 的优化,并提供诸如循环引用和动态绑定等高级功能。

什么是 ‘tree-shaking’?

Tree-shaking, 也被称为 "live code inclusion," 它是清除实际上并没有在给定项目中使用的代码的过程,但是它可以更加高效。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WflynnWeb 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ES6 模块与 CommonJS 模块的差异
  • 为什么ES模块比CommonJS更好?
  • 什么是 ‘tree-shaking’?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档