几天前面试时,被问到闭包相关的知识,其中有个问题是,以下函数形成闭包了吗?为什么?
// 代码一
function foo() {
let index = 1;
setTimeout(() => {
console.log(index);
}, 1000);
}
foo();
// 代码二
function foo() {
let index = 1;
const fn = function () {
console.log(index);
}
}
foo();
回答这个问题之前,我们首先得清楚什么是闭包。
红宝书中的定义: 闭包指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现。
闭包的作用:它可以保留变量被定义时的作用域;这种情况下闭包内部可以外部函数作用域中的变量,即便外部函数已经执行完毕。
因此,要判断是不是闭包,应该具备以下条件:
- 内部函数引用了外部函数作用域中的变量
- 能够通过外部函数调用内部函数
现在来看文章开头的问题:
-
代码一中调用 foo() 函数,一秒之后会调用延时函数,打印1。foo() 函数满足上文提到的判断闭包的条件。
-
代码二中调用 foo() 函数,不会得到任何结果,因为虽然定义了 fn() 函数,fn() 函数内也调用了外部函数作用域中的变量,但是我们无法通过任何手段调用 fn() 函数,不满足上文提到的第二个条件,因此代码二中不是闭包。
将代码二改成如下代码,会形成闭包:
// 代码三
function foo() {
let index = 1;
const fn = function () {
console.log(index);
}
fn();
}
foo();