模块化 JS 初步理解CommonJS
模块化的开发方式可以提高代码复用率,方便进行代码的管理。通常一个文件就是一个模块,有自己的作用域,只向外暴露特定的变量和函数。目前流行的js模块化规范有CommonJS、AMD、CMD以及ES6的模块系统。
为什么模块化?
- 解决命名冲突,全局污染
- 模块内部逻辑的封装性隔离
- 模块之间的通讯(依赖引用、循环引用、引用顺序)
目前大部分的模块化方案都是以闭包为基础的,那么什么是闭包?
(function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
})
可以初步理解为私有方法,名为 privateCounter 的变量和名为 changeBy 的函数。这两项都无法在这个匿名函数外部直接访问。必须通过匿名函数返回的三个公共函数访问。
CommonJS
// greeting.js
const prefix = 'hello';
const sayHi = function() {
return prefix + 'world';
}
module.exports = {
sayHi
}
// index.js
const { sayHi } = require('./greeting');
sayHi();
我们使用 module.exports 导出了 sayHi 函数,而在 index.js 中 greeting.js 的其他变量并不可以访问。
在编译的过程中,实际 CommonJS 对 JS 的代码块进行了首尾包装, 我们以上述的 greeting.js 为例子,它被包装之后的样子如下:
(function(exports,require,module,__filename,__dirname){
const prefix = 'hello';
const sayHi = function() {
return prefix + 'world';
}
module.exports = {
sayHi
}
})
和上边示例的闭包是不是有些相似?
而 require() 返回值就是 module.exports,所以,在 index.js 中使用的 require() 本质上也是一个函数,使用 const {} = require('') 赋值很像是解构赋值,比较一下是不是全都对上了。
总结
这篇文章实在太好了,有时间可以仔细看看!