How does arguments.callee refer to anonymous functions?

A script needed to quickly tell me how many html comments there are on the page and what their content is. Using an anonymous function to recursively traverse the DOM seemed appropriate:

var comments = []; //set up an array where comment contents will be copied to (function(D) { if (8===D.nodeType) comments.push(D.nodeValue); //check if node is a comment D=D.firstChild; while (D) { arguments.callee(D); //recursively look for comments... D=D.nextSibling; //...and remember to iterate over all children of any node } })(document); console.log(comments.join("\r\n")); //list all comments 

Fiddle works as expected, but I was curious if it was the same function called over and over again, or there were multiple references to the original function called or there were several identical functions called ... In the end, there was no named link, so how will it work, since the bypass goes deeper? I thought I could verify this by adding the following code to while (D) {...}

 //tmpCallee has been declared if (tmpCallee) { console.warn(arguments.callee === tmpCallee);//true /*great, means these should be both pointing to the same function*/ console.log(arguments.callee === arguments.caller);//false /*wait, what? didn't we just establish above that all of our functions called recursively would be the same?*/ console.log(arguments.caller);//undefined... but it was called recursively! console.log(arguments.callee);//prints our function code verbatim as it should } tmpCallee = arguments.callee; 

I'm confused. 1) Do I really call the same function over and over again, or are there several identical functions called or something else in the game? 2) why arguments.caller does not point to our function? it was explicitly called by him - how does recursion work, no?

+1
javascript anonymous-function recursion
source share
3 answers

Am I really calling the same function over and over again, or are there several identical functions that are called or something else in the game?

Yes, you only have one instance of the function that you reference all the time. However, you set up a call stack in which local variables (in your case, argument D ) will be saved for each call.

why don't .caller arguments point to our function?

The arguments object does not have a caller property; it has been deleted . You probably meant the caller property of a function object, which is non-standard, but still usable (although it is forbidden in strict mode, as well as argments.callee ).

+1
source share

There is only one instance of the function. This function calls itself recursively. You can easily verify this by assigning a name to the function expression in your code:

 (function fn (D) { 

and then inside the body:

 fn === arguments.callee // => true 

The above will be true for each call, indicating that only one function was created and called in this process.

In addition, these are:

 arguments.callee === arguments.callee.caller // => true, except first time 

shows that the function calls itself, i.e. Caller The above expression is true for every call except the first, because the first call came from global code.

Live demo: http://jsfiddle.net/HbThh/2/

+1
source share

There is no caller property for arguments , you should use arguments.callee.caller to get caller .

0
source share

All Articles