Levi Hackwith
Levi Hackwith

Reputation: 9332

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

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);
            }
        })();
    },

The code above is from Secrets of the JavaScript Ninja by John Resig. the part I don't understand is where he assigns a function to the property of start and then names that function runNext. Can someone please offer some clarification?

Upvotes: 3

Views: 114

Answers (2)

user2246674
user2246674

Reputation: 7719

The "name" of a function also serves a special role which is particularly useful when used in a 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?

Unlike x, theFunc above will always refer to the particular function-object. Without this name an additional closure (or use of this plumbing) would be required to access the function recursively. Also, the tight binding makes theFunc independent of the current this binding, which may be good or bad - note that after the call to setTimeout, theFunc will be called in a different binding context (which also makes the use of this.timerID suspect).

In ECMAScript 3rd edition, then function name (Identifier) and arguments.callee would evaluate to the same function-object inside the scope. However, arguments.callee is invalid per ECMAScript 5th edition "strict" mode.

The name may also show up in stack-traces, toString() and name/displayName (as implemented).


1From ES5 Annotated, Function Declarations:

The Identifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively ..

Upvotes: 2

Francisco Zarabozo
Francisco Zarabozo

Reputation: 3751

In JavaScript, everything is an object with members, and those members can serve as properties or methods according to what you put in them.

In this case, timer will have some members that will be used as methods (add and start). In order to do that, they will contain references to function code. The only reason he gives a name to the code reference in start (runNext), is so he can recursively call that function again from inside. The second function reference you see inside runNext, is another anonymous function reference that is not even being assigned to anything, but it's just there to make it return something at that moment for runNext.

Upvotes: -1

Related Questions