MST

星途 面试题库

面试题:TypeScript中let和const在块级作用域与闭包中的表现差异

编写一段TypeScript代码,展示let和const在块级作用域内,与闭包结合使用时的不同行为。解释为什么会出现这些不同,并说明这种差异在实际开发中的潜在影响。
33.3万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

代码示例

// 使用let
function letClosureExample() {
    let values: number[] = [];
    for (let i = 0; i < 3; i++) {
        values.push(() => i);
    }
    return values;
}

// 使用const
function constClosureExample() {
    let values: (() => number)[] = [];
    for (let j = 0; j < 3; j++) {
        const k = j;
        values.push(() => k);
    }
    return values;
}

// 测试letClosureExample
let letFuncs = letClosureExample();
letFuncs.forEach((func, index) => {
    console.log(`let闭包结果 ${index}:`, func());
});

// 测试constClosureExample
let constFuncs = constClosureExample();
constFuncs.forEach((func, index) => {
    console.log(`const闭包结果 ${index}:`, func());
});

不同行为及原因

  1. let
    • letClosureExample中,for循环内使用let声明ilet声明的变量在块级作用域内有效,并且每次循环迭代时,i会创建一个新的块级作用域实例。当将函数() => i推入数组时,每个函数捕获的是对应迭代时i的特定实例。所以,调用这些函数时,会输出012
  2. const
    • constClosureExample中,for循环内使用const声明k。虽然const声明的变量也是块级作用域,但它一旦声明就不能重新赋值。在每次循环迭代时,k捕获的是当前迭代的j的值。因为const的特性,它不会像let那样因为循环迭代而创建新的实例,而是在块级作用域内保持初始值。所以,每个闭包函数捕获的是当时k的固定值,调用这些函数时,同样会输出012

实际开发中的潜在影响

  1. let
    • 优势在于处理需要在循环中创建多个独立状态的场景,例如创建多个定时器,每个定时器需要捕获不同的迭代值。
    • 劣势是如果不小心,可能会因为块级作用域内变量的重新声明和修改导致难以调试的错误。
  2. const
    • 优势在于可以明确表明变量值不会改变,增强代码的可读性和可维护性,尤其在捕获不变的值用于闭包时。
    • 劣势是如果在需要更新值的场景下使用const,会导致语法错误,需要开发者仔细考虑是否需要可变的变量。