闭包何时捕获javascript中的变量值(在外部函数中定义):何时定义或执行嵌套函数?

3 javascript variables closures scope

我知道在定义函数时会创建作用域。但是我不确定我是否正确理解了在定义嵌套函数或执行嵌套函数时是否也捕获了变量值(在函数中定义并在内部函数中引用,也称为闭包)。

在众所周知的闭包循环方案中,闭环似乎在循环结束时捕获了“ 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 
Run Code Online (Sandbox Code Playgroud)

方案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 
Run Code Online (Sandbox Code Playgroud)

情况3

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

Que*_*tin 5

变量当它宣布被捕获。该值捕获(这就是它可以更改的原因)。

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; };
};
Run Code Online (Sandbox Code Playgroud)

  • @Charles:代码“var x = 0”实际上包含在完全不同的时间发生的两个完全独立的事情:它是一个变量声明(“var x”),它是一个赋值操作(“x = 0”)。函数内的所有变量声明都会在调用函数时、在处理任何分步代码之前进行处理。因此,即使 `var x` 向下 10 行,它也会在这些行运行之前被处理。这就是为什么人们说这些声明被“提升”到了最高层。不过,*作业*仍保留在原处。 (2认同)
  • @Charles:在上面的第二个示例中,“fnName”中的“x”是在“fnName”运行时创建并分配的,而不是在运行它返回的函数时创建和分配的。例如,“f = fnName();”创建“x”变量,“f”将覆盖该变量。调用 `f()` *使用*该变量。 (2认同)