MST

星途 面试题库

面试题:JavaScript模块模式的作用域与闭包

在JavaScript基于闭包的模块模式中,公有方法访问私有变量时,作用域链是如何形成和工作的?请结合具体代码详细分析。如果有多个模块实例,它们的私有变量和作用域之间的关系是怎样的?
27.9万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

闭包与模块模式中作用域链形成及工作原理

  1. 代码示例
// 创建模块
const myModule = (function () {
    let privateVariable = 'I am private';
    function privateFunction() {
        console.log('This is a private function');
    }
    return {
        publicMethod: function () {
            privateFunction();
            console.log(privateVariable);
        }
    };
})();
  1. 作用域链形成
    • publicMethod 被定义时,它的作用域链由两部分组成:它自己的局部作用域(在这个例子中为空,因为没有在 publicMethod 内定义局部变量)和它被创建时所在的外部作用域。
    • 这里 publicMethod 是在立即执行函数表达式(IIFE)内部创建的,所以它的外部作用域就是这个 IIFE 的作用域。在 IIFE 的作用域中,定义了 privateVariableprivateFunction
  2. 作用域链工作原理
    • publicMethod 被调用时,JavaScript 引擎会首先在 publicMethod 自己的局部作用域中查找变量和函数。如果找不到,就会沿着作用域链向上,到它的外部作用域(即 IIFE 的作用域)查找。
    • 例如在 publicMethod 中调用 privateFunction 和访问 privateVariable,因为在 publicMethod 自身局部作用域找不到,就会在 IIFE 作用域找到并执行/访问。

多个模块实例的私有变量和作用域关系

  1. 代码示例
// 创建模块工厂函数
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();
  1. 关系分析
    • 每个模块实例都有自己独立的私有变量和作用域。因为每次调用 moduleFactory 函数,都会创建一个新的作用域,这个作用域中的 privateVariableprivateFunction 都是独立的。
    • 所以 moduleInstance1moduleInstance2privateVariable 是相互独立的,修改其中一个实例的 privateVariable 不会影响另一个实例的 privateVariable。它们各自的 publicMethod 访问的是各自作用域中的私有变量和函数。