【问题标题】:When does the closure capture the variable value (defined in an outer function) in javascript: when nested function is defined or executed?闭包何时在javascript中捕获变量值(在外部函数中定义):何时定义或执行嵌套函数?
【发布时间】:2014-01-10 19:46:40
【问题描述】:

我了解在定义函数时会创建范围。但是我不确定我是否正确理解变量值(在函数中定义并在内部函数中引用,又名闭包)是否也在定义嵌套函数时被捕获,或者,当它被执行时。

在循环场景中众所周知的闭包中,闭包似乎在循环结束时捕获了“i”值。假设循环 5 次,那么“i”就是 4。因此“i”会被捕获为 4。因此看起来“i”是仅在执行嵌套函数时才被捕获?

如果有人能指出捕获发生的位置,我们将不胜感激。

场景 1

var fnName = function(x){           
    return function(){ return ++x; };   // (is x value captured here?)
};
var fnName1 = fnName(0);    
fnName1();              // x=1 (is x value captured here?)
fnName1();              // x=2 

场景 2

var fnName = function(){    
var x = 0;  
    return function(){ return ++x; };   // (is x value captured here?)
};
var fnName1 = fnName(); 
fnName1();              // x=1 (is x value captured here?)
fnName1();              // x=2 

场景 3

var fnName = function(){            
    var x = 0;              
    function runFn(){ return x++; };    // (is x value captured here?)
    runFn();            
};
fnName();               // x=0
fnName();               // x=0

【问题讨论】:

  • 要理解的关键是闭包不会关闭变量的,它们会关闭变量。它们具有对实际变量的持久引用,而不是其在特定时间点的值。
  • @T.J.Crowder 谢谢。这为我阐明了一些不同的概念。
  • @Charles:乐于助人。您可能会发现我的博客文章很有用:Closures are not complicated.
  • @T.J.Crowder 奇怪的是,当我过去搜索闭包或范围时,这篇文章并没有出现在谷歌搜索中。但这是我需要的确切文章。谢谢。

标签: javascript variables scope closures


【解决方案1】:

变量在声明时被捕获。值没有被捕获(这就是它可以改变的原因)。

var fnName = function(x){ // Here
    return function(){ return ++x; };
};


var fnName = function(){    
var x = 0;  // Here (but remember that hoisting exists)
    return function(){ return ++x; };
};

【讨论】:

  • 谢谢。看来我滥用了“捕获”术语。在这种情况下,调用嵌套函数时发生变量提升和初始化是否正确?
  • @Charles:代码var x = 0 实际上包含两个完全不同的事情,它们发生在完全不同的时间:它是一个变量声明(var x),它是一个赋值操作(x = 0)。函数中的所有变量声明都在函数被调用时被处理,任何分步代码被处理之前。因此,即使var x 下降了 10 行,它也会在这些行运行之前进行处理。这就是为什么人们说这些声明被“提升”到了最高点。但是,assignment 保持在原来的位置。
  • @Charles:在上面的第二个示例中,fnName 中的x 是在运行fnName 时创建和分配的,而不是在运行它返回的函数时。例如,f = fnName(); 创建 x 变量,f 关闭。调用f()使用该变量。
猜你喜欢
  • 2023-03-24
  • 1970-01-01
  • 2022-01-03
  • 2021-08-20
  • 1970-01-01
  • 2021-12-21
  • 2018-08-31
  • 2019-09-22
  • 2014-01-27
相关资源
最近更新 更多