CommonJS模块实现单例模式应使用let还是var声明变量?
CommonJS 单例场景下 var 与 let 的差异及选择
直接给结论
这个场景下两者功能完全一致,没有差异,优先选let。
原因解释
首先要明确CommonJS的核心规则:每个JS文件都是独立的模块作用域,所有在模块顶层声明的变量,不管用var、let还是const,都只会存在于当前模块的作用域里,不会污染全局。
你贴的代码里singleton是直接声明在模块顶层的,不属于任何{}包裹的块级作用域:
var的作用域是函数/模块级,顶层声明的话覆盖整个模块范围let虽然是块级作用域,但顶层的块本身就是整个模块的作用域,可访问范围和var完全重合
所以导出的闭包不管用哪个声明,都能正常读取、修改singleton的值,单例的逻辑不会有任何区别。
更稳妥的写法
虽然两者都能用,但现代JS开发早就不推荐用var了,var的变量提升、允许重复声明的特性很容易写出隐藏bug,所有场景优先用let就对了。
如果担心singleton被意外赋值覆盖,还可以改成const存引用的写法,更安全:
const singletonContainer = { instance: null } module.exports = () => singletonContainer.instance ? singletonContainer.instance : singletonContainer.instance = newInstance()
什么时候两者会有差异?
只有当变量声明在非顶层的块级作用域内时才会出现差异,比如:
// 随便写个块 { var testVar = 1 let testLet = 2 } console.log(testVar) // 输出1,var会提升到模块顶层 console.log(testLet) // 直接报错,let只在块内生效
你这个单例场景完全不会涉及到块内声明的情况,所以不用纠结差异,直接用let就行。
内容的提问来源于stack exchange,提问作者phramos07
相关产品推荐
相关产品推荐

