javascript闭包规则和范围链

时间:2013-12-25 03:09:18

标签: javascript closures scope-chain

关闭规则是:使用在定义时生效的范围链执行函数。

在下面的setTimeout回调函数中,x在定义时尚未在范围内。因此,程序应该打印undefined,但它打印7,为什么?我错过了什么?

var foo = function () {
    setTimeout(function (){
        console.log(x);
    }, 3000);
};

var x = 7;
foo();

或者,是因为上面的代码与下面的代码完全相同?

var x = 7;

var foo = function () {
    setTimeout(function (){
        console.log(x);
    }, 3000);
};

foo();

1 个答案:

答案 0 :(得分:3)

  

x在定义时尚未在范围内

事实并非如此。原因是吊装。基本上,JavaScript会将任何var或名为function的内容移动到包含范围的顶部。所以你真正拥有的是更像这样的东西:

// these variables are hoisted
var x;
var foo;

// then the variables are assigned.
foo = function () {
    setTimeout(function (){
        console.log(x);
    }, 3000);
};

x = 7;
foo();

Read more on hoisting here.


此外,这是准确的:

  

函数使用在定义时生效的范围链来执行。

但你的解释并不准确。他们可以访问定义它们的范围,但不是在它们被定义的时候。变量可以具有随时间变化的值,并且在这些范围中声明的函数将使用来自该范围的那些最新值。没有时间机器。

因此,当嵌套函数执行时,foo7,因为在该范围内,foo实际上是7