views:

124

answers:

1

I was browsing the JIT's code, and I saw this:

   var isGraph = ($type(json) == 'array');
    var ans = new Graph(this.graphOptions);
    if(!isGraph) 
        //make tree
        (function (ans, json) {
            ans.addNode(json);
            for(var i=0, ch = json.children; i<ch.length; i++) {
                ans.addAdjacence(json, ch[i]);
                arguments.callee(ans, ch[i]);
            }
        })(ans, json);
    else
        //make graph
        (function (ans, json) {
            var getNode = function(id) {
                for(var w=0; w<json.length; w++) { 
                  if(json[w].id == id) {
                    return json[w];
                  }
                }
                return undefined;
            };

What could be the purpose for those anonymous functions? They immediately pass out of scope, right?

Why use:

        (function (ans, json) {
            ans.addNode(json);
            for(var i=0, ch = json.children; i<ch.length; i++) {
                ans.addAdjacence(json, ch[i]);
                arguments.callee(ans, ch[i]);
            }
        })(ans, json);

instead of:

            ans.addNode(json);
            for(var i=0, ch = json.children; i<ch.length; i++) {
                ans.addAdjacence(json, ch[i]);
                arguments.callee(ans, ch[i]);
            }

Is this some super elite JS hack?

+12  A: 

They just want to implement recursion in that small piece of code:

    (function (ans, json) {
        ans.addNode(json);
        for(var i=0, ch = json.children; i<ch.length; i++) {
            ans.addAdjacence(json, ch[i]);
            arguments.callee(ans, ch[i]); // <-- recursion!
        }
    })(ans, json);

The arguments.callee property refers to the currently executing function, if you remove the anonymous function, it will refer to the enclosing function, and I don't think they want to invoke the whole function again.

CMS
Interesting. I've never seen `arguments.callee` used before.
Rosarch
You also could give the function expression an identifier. In ECMAScript 5 this is the preferred method.
ChaosPandion
@Chaos, Yes, is the preferred way, under [strict mode](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/) `arguments.callee` is disallowed on ES5... but using named function expressions *now* can cause problems, because IE has a serious, long-standing bug, where the identifier of function expressions, lacks to the enclosing scope, actually, two function objects are created... This bug even exist on IE9 Platform Preview... Sad... See also: [Named function expressions demystified](http://yura.thinkweb2.com/named-function-expressions/)
CMS