跳到正文
hello world
文章封面

【编程题与分析题】闭包问题

【编程题与分析题】闭包问题

闭包是JavaScript中的一个重要概念,它允许函数访问并操作其外部作用域的变量。本文将通过编程题和分析题,帮助读者更好地理解和掌握闭包的使用。

什么是闭包

闭包是指内部函数可以访问外部函数作用域中的变量,即使外部函数已经执行完毕。这种特性使得闭包在JavaScript中非常强大和灵活。

编程题

题目1:实现一个计数器

要求:编写一个函数,返回一个计数器函数,每次调用计数器函数时,计数器加1。

function createCounter() {
  let count = 0;
  return function() {
    return ++count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

题目2:实现一个记忆函数

要求:编写一个函数,返回一个记忆函数,记忆函数可以缓存之前计算的结果,避免重复计算。

function memoize(fn) {
  const cache = {};
  return function(...args) {
    const key = JSON.stringify(args);
    if (cache[key]) {
      return cache[key];
    } else {
      const result = fn.apply(this, args);
      cache[key] = result;
      return result;
    }
  };
}

const add = (a, b) => a + b;
const memoizedAdd = memoize(add);
console.log(memoizedAdd(1, 2)); // 3
console.log(memoizedAdd(1, 2)); // 3 (从缓存中获取)

分析题

题目1:闭包中的变量作用域

以下代码的输出是什么?为什么?

function outer() {
  let x = 10;
  return function inner() {
    console.log(x);
  };
}

const innerFunc = outer();
innerFunc(); // 输出什么?

答案:输出 10。因为闭包 inner 函数保留了对外部函数 outer 中变量 x 的引用,即使 outer 函数已经执行完毕。

题目2:闭包中的循环问题

以下代码的输出是什么?如何修正?

for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}

答案:输出 3 3 3。因为 var 声明的变量是函数作用域的,闭包共享同一个 i 变量,当 setTimeout 执行时,循环已经结束,i 的值为 3。

修正方法:使用 let 声明变量,或者使用闭包捕获每次循环的 i 值。

// 使用 let
for (let i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}

// 使用闭包
for (var i = 0; i < 3; i++) {
  (function(i) {
    setTimeout(function() {
      console.log(i);
    }, 1000);
  })(i);
}

总结

闭包是JavaScript中的一个重要特性,它允许函数访问外部作用域的变量。通过编程题和分析题,我们可以更好地理解闭包的使用场景和注意事项。掌握闭包对于编写高质量的JavaScript代码至关重要。

评论

填写昵称与邮箱即可评论,无需登录。

推荐阅读