首页 > 解决方案 > 了解 JavaScript 中的闭包范围

问题描述

我一直在阅读“You Don't Know JS”系列丛书,我有一个关于闭包的问题。

var a;

function wait() {
  a = 10;

  return setTimeout(function timer() {
    console.log('Hello closure ', a);
  }, 1000)
}

const fn = wait;
fn();
console.log(a);

如果我在控制台中询问a的值而不执行函数 (fn()),它会说它是未定义的,这是正确的。

现在,如果我在 1 秒后执行函数fn(),它将打印Hello Closure 10我知道计时器对等待函数有一个闭包,这就是它打印该值的原因,即使它是在定义它的词法范围之外执行的。

但是如果现在在控制台中打印一个值(在运行 fn() 之后)它也会输出10,所以我猜这不是词法范围,从全局范围来看,查找永远不会下降(我的意思是它在嵌套函数中看起来很深),它总是向上查找变量(向上到函数的封闭范围)。

所以我想知道这是否也是闭包,或者变量在运行函数后刚刚获得了另一个值,仅此而已?

标签: javascriptclosurestheory

解决方案


如果在函数内部实例化变量,它将防止同名的全局变量发生变化。我var a = 10在函数中添加了一个。我将全局范围的 var 留在那里,所以你可以看到它现在没有改变。这更像是一个变量范围问题。

闭包按预期工作,只是您设置了一个全局变量。

var a;
function wait() {
  var a = 10;

  return setTimeout(function timer() {
    console.log('Hello closure ', a);
  }, 1000)
}

const fn = wait;
fn();
console.log(a);


推荐阅读