为什么这种关闭工作?

时间:2012-03-01 15:47:06

标签: javascript closures

假设我有一个提醒消息的简单功能:

function callMessage(msg){
        alert(msg);
    }

现在,当我这样称呼它时,它不起作用。引发错误“嘿未定义”

function sayHi(){
        var hey = "hi there"
        setTimeout("callMessage(hey)", 1000);
    }
    sayHi();

但是当我在一个匿名函数中调用它时它确实有效:

function sayHi(){
        var hey = "hi there"
        setTimeout(function(){callMessage(hey);}, 1000);
    }
    sayHi();

为什么“hey”变量只有在我将其放入匿名函数时才可见?

3 个答案:

答案 0 :(得分:14)

在第一个示例中,在计时器到期之后评估代码,并保留当前范围。那时hey未定义。

第二个示例 - 使用setTimeout的正确方法 - 使用在调用setTimeout()时创建的匿名函数。此匿名函数还会收到当前范围的副本。

答案 1 :(得分:6)

“callMessage(hey)”是一个字符串,而不是一个闭包。它在超时运行时进行评估,此时变量hey不在范围内。

答案 2 :(得分:3)

这是正常的。

第二个例子创建了我们称之为fixture的东西,这是一个执行上下文。保存变量变量以供内存中的匿名函数使用。

在你的第一个例子中,hey变量没有保存在fixture中(因为javascript不能知道你之后会使用变量)因此在评估字符串时无法检索