PDA

View Full Version : If I have the following code...


\\.\
05-22-2007, 08:07 PM
I would like to get the name of the function that called the function.

example.

// the popup will show the source of the function that called the function popup

function popup(){
calledby = popup.caller;
alert(calledby);
}


function cheese(){
popup();
}

function onion(){
popup();
}

onion(); // when onion() is called, the output is an alert box with

function onion(){
popup();
}


With the method below
//with this method, no function name is vivible!
popup ={
msg:function(){calledby = this.msg.caller; alert(calledby);},
cheese:function(){
this.msg();
},
onion:function(){
this.msg();
}
}

popup.onion(); // when called, the output doesn't show the function name or caller
However, the following is the result of the above method

function (){
this.msg();
}
So how can I find the name of the whole function when it is not known?

I have tried toSource, toString, valueOf and they only output [object Object] undefined or the body of the function, not the name.

any ideas?

glenngv
05-22-2007, 09:33 PM
That's an anonymous function that's why it has no name. Why don't you just pass the name as a parameter? What is your ultimate need?

\\.\
05-23-2007, 08:21 PM
because I need to use the reference 'this' and need to be able to grab the name of the caller in full. This makes for easier function writing, checking who called what and also for internal stuff in my more complex routines.

Passing the name of the function as a parameter is a bit sloppy.

felgall
05-23-2007, 08:55 PM
If it doesn't have a name then you can't retrieve it regardless of which way you have the code. If you want to be able to retrieve the function name you need to give the function a name to start with and not use an anonymous function that doesn't have a name.

\\.\
05-28-2007, 11:16 PM
I cant believe that javascript has no method of finding out who actually called the function what was used and any parameters passed in the call or just the name of the function...

felgall
05-29-2007, 12:18 AM
The method you are using will give the name when there is one but the code you are using isn't giving the function a name and so there is no name to get.

onion:function(){
this.msg();
}

The function in this code does not have a name - it has used an anonymous function definition where no name is assigned to it.

To assign a name to a function you have to declare it using

function NAME()

liorean
05-29-2007, 01:42 PM
I cant believe that javascript has no method of finding out who actually called the function what was used and any parameters passed in the call or just the name of the function...JavaScript actually has pretty good reflection and introspection facilities compared to most languages. You just need to understand it's workings a little bit better.

- You can always find out which object a function was called as the method of using the this keyword.
- You can always find out which arguments were sent to it using the arguments local variable.
- You can always find out which function is actually running using arguments.callee.
- You can most of the time find out which function called the function that is actually running using arguments.callee.caller.

However, functions are objects in JavaScript, and methods are simply properties with a value being a function object. Let me give you some code that shows my point:
function foo(){
return{
'this':this,
'arguments':arguments,
'arguments.callee':arguments.callee,
'arguments.callee.caller':arguments.callee.caller};
}
function notfoo(){
return{
'this':this,
'arguments':arguments,
'arguments.callee':arguments.callee,
'arguments.callee.caller':arguments.callee.caller};
}
function testCaller(prop,obj){
obj=obj||window;
return obj[prop](prop,obj);
}

function displayInformation(obj){
var
i,
c,
o,
key,
data=[],
arr=[];
for(key in obj)
data.push('obj[\'' + key + '\']:\n' + obj[key]);
alert('Just stringified:\n----\n' + data.join('\n\n\n'));
arr.push('this === oogle? ' + (obj['this']===oogle));
for(i=0,o=obj['arguments'],c=o.length;i<c;i++)
arr.push('Argument ' + i + ': ' + o[i]);
o=obj['this'];
for(key in o)
arr.push('arguments.callee === this[\'' + key + '\']: ' + (o[key]===obj['arguments.callee']));
arr.push('arguments.callee.caller === testCaller: '+(obj['arguments.callee.caller']===testCaller));
alert('With minimal effort:\n----\n' + arr.join('\n\n'))
}
var
oogle={
bar:foo,
boogle:notfoo,
baz:foo};

displayInformation(testCaller('bar',oogle));
displayInformation(testCaller('boogle',oogle));
displayInformation(testCaller('baz',oogle));
displayInformation(testCaller('foo'));
displayInformation(testCaller('notfoo'));You haven't named your functions, and they have identical function bodies, so you can't tell the difference between them in a plain stringification. Neither would you be able to tell the difference between foo and notfoo when stringified except for the name. However, you can still programatically compare the functions and find out if they are the same or not.


One thing you can't tell, however, is HOW a function got called. It doesn't matter to JavaScript if you call a function through oogle.bar(), oogle.baz() or foo.call(oogle) they are all three different ways of doing exactly the same thing: a call on the function foo as a method of oogle.

\\.\
05-30-2007, 01:09 AM
Thanks for the light bed time read!

I get the idea. Will have a play with it sometime this week.

Thanks.