闭包与模块模式中作用域链形成及工作原理
- 代码示例
// 创建模块
const myModule = (function () {
let privateVariable = 'I am private';
function privateFunction() {
console.log('This is a private function');
}
return {
publicMethod: function () {
privateFunction();
console.log(privateVariable);
}
};
})();
- 作用域链形成
- 当
publicMethod
被定义时,它的作用域链由两部分组成:它自己的局部作用域(在这个例子中为空,因为没有在 publicMethod
内定义局部变量)和它被创建时所在的外部作用域。
- 这里
publicMethod
是在立即执行函数表达式(IIFE)内部创建的,所以它的外部作用域就是这个 IIFE 的作用域。在 IIFE 的作用域中,定义了 privateVariable
和 privateFunction
。
- 作用域链工作原理
- 当
publicMethod
被调用时,JavaScript 引擎会首先在 publicMethod
自己的局部作用域中查找变量和函数。如果找不到,就会沿着作用域链向上,到它的外部作用域(即 IIFE 的作用域)查找。
- 例如在
publicMethod
中调用 privateFunction
和访问 privateVariable
,因为在 publicMethod
自身局部作用域找不到,就会在 IIFE 作用域找到并执行/访问。
多个模块实例的私有变量和作用域关系
- 代码示例
// 创建模块工厂函数
function moduleFactory() {
let privateVariable = 'I am private';
function privateFunction() {
console.log('This is a private function');
}
return {
publicMethod: function () {
privateFunction();
console.log(privateVariable);
}
};
}
// 创建两个模块实例
const moduleInstance1 = moduleFactory();
const moduleInstance2 = moduleFactory();
- 关系分析
- 每个模块实例都有自己独立的私有变量和作用域。因为每次调用
moduleFactory
函数,都会创建一个新的作用域,这个作用域中的 privateVariable
和 privateFunction
都是独立的。
- 所以
moduleInstance1
和 moduleInstance2
的 privateVariable
是相互独立的,修改其中一个实例的 privateVariable
不会影响另一个实例的 privateVariable
。它们各自的 publicMethod
访问的是各自作用域中的私有变量和函数。