将一个函数命名为对象中属性的值的目的是什么?

What is the purpose of naming a function that is a value of a property in an object?

本文关键字:属性 是什么 对象 命名为 函数 一个      更新时间:2023-09-26
var timers = {                                                  //#1
    timerID: 0,                                                   //#2
    timers: [],                                                   //#2
    add: function(fn) {                                           //#3
        this.timers.push(fn);
    },
    start: function runNext() {                                   //#4
        if (this.timerID) return;
        (function() {
            if (timers.timers.length > 0) {
                for (var i = 0; i < timers.timers.length; i++) {
                    if (timers.timers[i]() === false) {
                        timers.timers.splice(i,1);
                        i--;
                    }
                }
                timers.timerID = setTimeout(runNext, 0);
            }
        })();
    },
上面的代码来自John Resig的Secrets of The JavaScript Ninja。我不明白的是他给start赋了一个函数,然后把这个函数命名为runNext。有人能解释一下吗?

函数的"name"还有一个特殊的作用,在FunctionExpression1:

中使用时特别有用。
x = function theFunc (z) {
    // theFunc is in scope here, and so can be used to refer
    // to the function itself in a recursive manner
    //   (in the posted code it is used with setTimeout)
    return z > 0 ? theFunc(z - 1) * z : 1;
};
// theFunc is NOT in scope here in valid ECMAScript; IE quirks anyone?
x不同的是,上述theFunc 总是表示特定的函数对象。如果没有这个名称,则需要一个额外的闭包(或使用this管道)来递归访问该函数。此外,紧密绑定使theFunc独立于当前的this绑定,这可能是好的,也可能是坏的-请注意,在调用setTimeout之后,theFunc将在不同的绑定上下文中被调用(这也使this.timerID的使用受到怀疑)。

在ECMAScript第三版中,然后是函数名(标识符)和参数。Callee将计算为作用域中相同的函数对象。然而,参数。calllee在ECMAScript第5版"strict"模式下无效。

名称也可能出现在堆栈跟踪,toString()name/displayName(如实现)。


1From ES5 Annotated, Function Declarations:

FunctionExpression中的Identifier可以从FunctionExpression的FunctionBody内部引用,以允许函数递归地调用自己。

在JavaScript中,任何东西都是带有成员的对象,这些成员可以作为属性或方法,这取决于你在其中放入了什么。

在这种情况下,timer将有一些成员用作方法(addstart)。为了做到这一点,它们将包含对function代码的引用。他给start (runNext)中的代码引用命名的唯一原因是他可以从内部递归地再次调用该函数。您在runNext中看到的第二个函数引用是另一个匿名函数引用,它甚至没有被分配给任何东西,但它只是在那里使它在那一刻为runNext返回一些东西。