MST

星途 面试题库

面试题:JavaScript 函数作用域与闭包问题

请解释 JavaScript 中函数作用域和闭包的概念,并举例说明闭包在实际开发中的应用场景。
35.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

函数作用域

函数作用域是指在函数内部声明的变量和函数,其作用域仅限于该函数内部。在函数外部无法访问函数内部声明的变量,这有助于防止变量命名冲突。例如:

function myFunction() {
    let localVar = 10; // localVar 具有函数作用域
    console.log(localVar); 
}
myFunction(); 
console.log(localVar); // 这里会报错,localVar 在函数外部不可访问

闭包

闭包是指一个函数能够访问并记住其词法作用域,即使函数在其原始作用域之外执行。当内部函数在外部被返回或调用时,就形成了闭包。内部函数可以访问外部函数的变量,即使外部函数已经执行完毕。例如:

function outerFunction() {
    let outerVar = 10;
    function innerFunction() {
        console.log(outerVar); 
    }
    return innerFunction;
}
let closure = outerFunction();
closure(); 

闭包在实际开发中的应用场景

  1. 数据封装与私有化:通过闭包可以模拟私有变量,实现数据的封装。
function Counter() {
    let count = 0;
    function increment() {
        count++;
        return count;
    }
    return increment;
}
let counter = Counter();
console.log(counter()); 
console.log(counter()); 

在这个例子中,count 变量对于外部代码是私有的,只能通过 increment 函数来修改它的值。

  1. 事件处理与回调:在事件处理函数中,闭包可以用于保持特定的上下文和变量状态。
function setupButtonClickListener() {
    let message = 'Button was clicked!';
    let button = document.createElement('button');
    button.textContent = 'Click me';
    button.addEventListener('click', function() {
        console.log(message); 
    });
    document.body.appendChild(button);
}
setupButtonClickListener();

这里,message 变量在事件处理函数(闭包)中被记住,即使 setupButtonClickListener 函数已经执行完毕。

  1. 模块模式:闭包在实现模块模式时非常有用,模块可以暴露特定的接口,隐藏内部实现细节。
let myModule = (function() {
    let privateVar = 'This is private';
    function privateFunction() {
        console.log(privateVar);
    }
    return {
        publicFunction: function() {
            privateFunction();
        }
    };
})();
myModule.publicFunction(); 

在这个模块模式示例中,privateVarprivateFunction 对于外部代码是不可直接访问的,只有通过暴露的 publicFunction 才能间接使用它们。