动态函数的变量范围?

时间:2013-04-30 11:21:12

标签: javascript jquery

我是Javascript的新手,并编写了以下可运行的jQuery代码:

function updateItems() {
        var now = Math.round((new Date()).getTime() / 1000);

        $(".something").each(function() {

             $(this).html(now.toString());

        });
}

updateItems();

为什么这样做?有人可能会认为now无法从函数内部访问。我想我可以运行一些测试来看看如果我尝试从函数内部修改now会发生什么,如果我在那之后再运行另一个each(),等等。但是基本了解范围是如何工作的这里和一般在Javascript这样的情况将非常感谢。

此外,这种类型的功能是否准确地称为“动态功能”还是有更好的名称?

2 个答案:

答案 0 :(得分:5)

当您使用function() { ... }时,您可以创建技术上称为闭包的内容。它们可以有效地捕获封闭范围内的所有内容。

如果你在闭包中使用now,那么当你执行闭包时会得到now 的值,并且(可能)不是你在它时的值创造了它。

请注意,此处的封闭范围外部函数的范围,而不是外部块的范围,您可能需要采取例如,如果要在循环中创建闭包,请格外小心。

答案 1 :(得分:3)

这只是一个嵌套函数。它可以访问now变量,因为函数可以访问定义它们的范围内的变量(实际上这也是全局变量的工作方式)。它被称为“闭包”(它“关闭”其定义的范围内的变量),听起来模糊不清,但不要担心 - closures are not complicated (披露:我的博客)一次你知道关于JavaScript如何运作的一些事情。

这里有趣的是它关闭了now变量,该变量特定于对updateItems的特定调用,并且它的引用是 live (它不是创建函数时的now copy 。每次调用updateItems都会创建一个 new 匿名函数,并将其传递给each,并且每个函数都可以访问调用期间创建的now变量到updateItems。在你的情况下,你只是立即使用它并返回,但是如果你保留对函数的引用呢?然后怎样呢?答案很好,它保留了与它相关的now变量的引用:

function say(msg) {
    var f = function() {
        alert(msg);
    };
    return f; // We return a reference to the function
}
var s1 = say("Hi");
var s2 = say("there");
s1(); // Alerts "Hi" (see below)
s2(); // Alerts "there"

s1提醒"Hi"的来电,因为我们对say的调用所创建的功能仍然可以访问我们向msg提供的say参数,即使say已经返回。当然,s2也是如此。

并且只是为了证明它不是创建函数时的副本:

function say(msg) {
    // Create the function
    var f = function() {
        alert(msg);
    };

    // Update `msg`
    msg += " (updated)";

    // Return the function
    return f;
}
var s1 = say("Hi");
var s2 = say("there");
s1(); // Alerts "Hi (updated)"
s2(); // Alerts "there (updated)"

查看该函数如何使用msg的更新版本,即使该函数是在我们更新之前创建的。该函数可以访问变量本身,而不是变量值的副本