【编程题与分析题】闭包问题
闭包是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代码至关重要。

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