Reputation: 17617
I'm trying to write a helper method in JavaScript. It should act differently if one sends in a function or an reference to a function.
I want to like to use it like this:
helper('div', function () { return false; })
helper('div', obj.fn)
What I can't figure out is: how to inside the helper function tell the difference between the two?
I think it's due to that JavaScript first evaluates the obj.fn before it sends it in. The only workaround I found is to send the obj.fn as an obj, i.e.
helper('div', { fn: obj.fn })
Then I can tell the difference between the two with typeof. But I really like some way to make it without the extra object declaration.
Upvotes: 6
Views: 4523
Reputation: 344585
You can use toString()
to find out if the function is anonymous assuming it is declared as a named function and not an unnamed function assigned to a variable:
function jim () { var h = "hello"; }
function jeff(func)
{
var fName;
var inFunc = func.toString();
var rExp = /^function ([^\s]+) \(\)/;
if (fName = inFunc.match(rExp))
fName = fName[1];
alert(fName);
}
Will give you the name of the function if any.
jeff(function () { blah(); }); // alert: null;
jeff(function joe () { blah(); }); // alert: "joe";
jeff(jack); // "jack" if jack is function jack () { }, null if jack = function() {}
My previous edit referred to an IE quirk that didn't exist in other browsers and is no longer valid in IE as of version 9. However, you can still assign named functions as object properties using a named function expression:
var obj = {
fn: function namedFunction () { }
};
This works in all browsers, but IE 8 and lower don't adhere to the specification which says the function is only available by this name inside its own block.
Upvotes: 0
Reputation: 344585
I thought I'd add another alternative answer, mainly because I didn't want to add to the soup that is my other answer but also because it didn't go down to well with the stackoverflow voters that don't leave constructive comments ;-)
As an alternative to what you're trying to do, you could add a third parameter to the helper function:
function helper (tagName, fn, method)
{
if (method)
fn = fn[method];
//- Do rest of helper function here
}
//- Now if we pass an object method to helper function we can identify it properly
helper('div', obj, "fn"); // method is obj.fn
helper('div', function () { blah(); }); // Still works fine
Merely a suggestion and works as well as or even better than your current work-around.
Upvotes: 1
Reputation: 5879
UPDATED *(AGAIN): I thought that the toString() method might be your only way forward here. It doesn't however treat a reference of an anonymous object differently.
This code demonstrates that:
function acceptparam(fn){
console.log("fn.constructor = " + fn.constructor);
console.log("typeof fn = " + typeof fn);
console.log("fn toString " + fn.toString());
console.log("fn.prototype = " + fn.prototype);
console.log("fn.prototype.constructor = " + fn.prototype.constructor);
console.log("this[0] = " + this[0]);
console.log("---");
}
function empty(){
return ;
}
var x = {
y : function(){return;}
}
acceptparam(empty);
acceptparam(function(){return;});
acceptparam(x.y);
Very interesting question, without implementing your own solution I dont think you can do it, this post helps to explain why. Its about the parent child relationship only being one way.
http://codingforums.com/showthread.php?t=134855
Upvotes: 2