为什么这个闭包范围的变量会失去它的价值?

Sam*_*Sam 6 javascript closures

我在这里看到了这个Javascript测验:http://www.netfxharmonics.com/2008/01/NetFX-Harmonics-JavaScript-Quiz

我无法弄清楚这个问题:

(function(){
    var a = 1;
    var b = 2;

    (function( ) { a = b; var b; })( );

    console.log('a:'+ a);  // => "a:undefined"
    console.log('b:'+ b);  // => "b:2"
})()
Run Code Online (Sandbox Code Playgroud)

但是,如果var b;从内部函数中删除声明,那么a == 2正如您所期望的那样.

为什么会这样?

(你可以在这里玩它:http://jsfiddle.net/gnhMZ/)

T.J*_*der 8

它正在发生,因为这个功能:

(function( ) { a = b; var b; })( );
Run Code Online (Sandbox Code Playgroud)

......分配undefineda.var从编写范围的开头起生效,而不是在逐步编写代码的位置.当你声明一个变量时,它的初始值是undefined.所以上面写的更明确,但具有完全相同的功能,看起来像这样:

(function( ) {
    var b = undefined;
    a = b;
})( );
Run Code Online (Sandbox Code Playgroud)

具体来说,当执行进入执行上下文时,会发生以下情况:

  1. 为执行上下文创建幕后变量对象,并将其放在作用域链的顶部(用于解析非限定引用的变量对象链).
  2. var无论var语句在何处,都会在上下文中声明的每个变量对象上创建属性.每个变量的初始值是undefined.此时不处理初始化程序.
  3. 对于在上下文中声明的每个函数(使用函数声明,而不是函数表达式),在变量对象上创建属性,而不管函数声明在何处.
  4. 处理函数声明并将结果分配给这些函数的属性.
  5. 继续执行上下文中的第一行分步代码.var遇到带有初始值设定项的语句时,它将作为简单赋值语句处理.

变量对象是使关闭工作,也顺便的事情.更多这里,但基本上,当创建一个函数时,它会在该点获得对作用域链中所有变量对象的持久引用.这就是它用来查找它关闭的变量的用途.这是很重要的,因为封闭不只有一个持久引用它实际上使用的变量,但在范围内的所有变量在那里的定义,无论使用与否,它可以有这些变量的生命周期影响.