0

我对 Javascript 相当陌生,并编写了以下有效的 jQuery 代码:

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

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

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

        });
}

updateItems();

为什么这行得通?有人可能认为now从函数内部无法访问它。我想我可以运行一些测试来看看如果我尝试now从函数内部修改会发生什么,如果我在此之后运行另一个each()等等。但是对范围如何在这里以及通常在像这样的 Javascript 案例中如何工作的基本了解是非常感激。

另外,这种类型的函数是准确地称为“动态函数”还是有更好的名称?

4

2 回答 2

5

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

如果您now在闭包中使用,您将获得now 执行该闭包时的值,并且(可能)不是创建它时的值。

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

于 2013-04-30T11:23:55.487 回答
3

这只是一个嵌套函数。它可以访问now变量,因为函数可以访问定义它们的范围内的变量(这实际上也是全局变量的工作方式)。它被称为“闭包”(它“关闭”其定义范围内的变量),这听起来很晦涩,但不要担心——一旦你知道了一些关于如何的事情,闭包并不复杂 (披露:我的博客) JavaScript 有效。

这里有趣的是它关闭了now特定于特定调用的变量updateItems,并且它具有的引用是实时的(它不是创建函数时的副本now)。每次调用updateItems都会创建一个您传递给的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,即使该函数是在我们更新它之前创建的。该函数可以访问变量本身,而不是变量值的副本

于 2013-04-30T11:24:41.340 回答