关于JavaScript Closure如何工作的困惑

时间:2015-05-09 02:44:27

标签: javascript closures

我认为这是一个愚蠢的问题,但考虑到这个JavaScript代码......

function outerFun()
{
 var a=0;
 function innerFun()
 {
  a++;
  alert(a);
 }
 return innerFun;  
}
var obj=outerFun();
obj();  //1
obj();  //2
var obj2=outerFun();
obj2();  //1
obj2();  //2

我理解为什么在obj()的前两次调用中结果是1然后是2,但我很困惑为什么obj2()返回1并且在调用obj()两次后没有返回3。

3 个答案:

答案 0 :(得分:3)

因为每次调用outerFun()时,都会创建一个不同的新执行上下文,因此innerFun实际上并不是同一个东西,因为每个函数都引用innerFun你从outerFun返回的是一个不同的上下文,一个带有自己变量的上下文。

function outerFun()
{
 var a=0;
 function innerFun()
 {
  a++;
  alert(a);
 }
 return innerFun;  
}
var obj = outerFun();
var obj2 = outerFun();
console.log(obj === obj2);
// Not equal, because innerFun is a different innerFun for each function call,
// as it is the same function name, returned from the same function,
// but in a different context.
obj();  //1
obj();  //2
obj2();  //1
obj2();  //2

// Call obj twice, it'll increase to 4.
// While calling obj2 once again, leaves it at 3.
// This way you can know that obj and obj2 are not modifying
// the same variables.
// They are independent of each other.
obj(); // 3
obj(); // 4
obj2(); // 3

答案 1 :(得分:1)

运行outerFun()时,它会创建一个新函数并将其返回。每次调用它都会这样做。它返回的每个函数实际上都是一个全新的函数,与之前调用它时创建的函数无关,即使它们内部的代码是相同的。

当你达到这个陈述时......

var obj2=outerFun();

...您实际上正在创建一个在其父作用域中具有自己的a副本的新对象。因此,如果在实例化obj();后再次调用obj2,那么实际获得三个。它们每个都有自己的a变量。希望对该示例的这种修改是有道理的:

function outerFun()
{
    var a=0;
    function innerFun()
    {
        a++;
        alert(a);
    }
    return innerFun;  
}
var obj=outerFun();
obj();  //1
obj();  //2
var obj2=outerFun();
obj();  //3
obj();  //4
obj2();  //1
obj2();  //2
obj();  //5

有意义吗?

答案 2 :(得分:0)

当你第二次outerfun ()时,新的a被定义为值0。