首页 > 语言 > JavaScript > 正文

详谈commonjs模块与es6模块的区别

2024-05-06 15:25:30
字体:
来源:转载
供稿:网友

到目前为止,已经实习了3个月的时间了。最近在面试,在面试题里面有题目涉及到模块循环加载的知识。趁着这个机会,将commonjs模块与es6模块之间一些重要的的区别做个总结。语法上有什么区别就不具体说了,主要谈谈引用的区别。

commonjs

对于基本数据类型,属于复制。即会被模块缓存。同时,在另一个模块可以对该模块输出的变量重新赋值。

对于复杂数据类型,属于浅拷贝。由于两个模块引用的对象指向同一个内存空间,因此对该模块的值做修改时会影响另一个模块。

当使用require命令加载某个模块时,就会运行整个模块的代码。

当使用require命令加载同一个模块时,不会再执行该模块,而是取到缓存之中的值。也就是说,commonjs模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存。

循环加载时,属于加载时执行。即脚本代码在require的时候,就会全部执行。一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。

ES6模块

es6模块中的值属于【动态只读引用】。

对于只读来说,即不允许修改引入变量的值,import的变量是只读的,不论是基本数据类型还是复杂数据类型。当模块遇到import命令时,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。

对于动态来说,原始值发生变化,import加载的值也会发生变化。不论是基本数据类型还是复杂数据类型。

循环加载时,

上面说了一些重要区别。现在举一些例子来说明每一点吧

commonjs

对于基本数据类型,属于复制。即会被模块缓存。同时,在另一个模块可以对该模块输出的变量重新赋值。

// b.jslet count = 1let plusCount = () => { count++}setTimeout(() => { console.log('b.js-1', count)}, 1000)module.exports = { count, plusCount}// a.jslet mod = require('./b.js')console.log('a.js-1', mod.count)mod.plusCount()console.log('a.js-2', mod.count)setTimeout(() => { mod.count = 3 console.log('a.js-3', mod.count)}, 2000)node a.jsa.js-1 1a.js-2 1b.js-1 2 // 1秒后a.js-3 3 // 2秒后

以上代码可以看出,b模块export的count变量,是一个复制行为。在plusCount方法调用之后,a模块中的count不受影响。同时,可以在b模块中更改a模块中的值。如果希望能够同步代码,可以export出去一个getter。

// 其他代码相同module.exports = { get count () { return count }, plusCount}node a.jsa.js-1 1a.js-2 1b.js-1 2 // 1秒后a.js-3 2 // 2秒后, 由于没有定义setter,因此无法对值进行设置。所以还是返回2            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选