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.
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.
Share Improve this question edited Dec 11, 2011 at 23:44 Lightness Races in Orbit 386k77 gold badges666 silver badges1.1k bronze badges asked Dec 17, 2009 at 10:50 fredrikfredrik 17.6k9 gold badges56 silver badges71 bronze badges 7- 2 Do you have a specific reason, why you want to tell two functions apart? – Boldewyn Commented Dec 17, 2009 at 11:13
- 3 "It should act differently if one sends in a function or an reference to a function" - what does this mean? How do you define the difference between a "function" and a "reference to a function"? In your first example, the parameter passed to helper will be a reference to a function either way. – Tim Down Commented Dec 17, 2009 at 11:55
- 1 I still don't understand what the problem is. It would seem from the accepted answer below that you want to distinguish between named and anonymous functions. If so, why? – Tim Down Commented Dec 17, 2009 at 13:17
-
2
@fredrik: then you should have accepted Andy E's other answer (he posted two). Knowing if a function has a "name" doesn't give you anything. You cannot, cannot, execute a passed object function in it's correct scope just by knowing it was the result of
var f =
vsfunction f
. Even function expressions can be assigned a named function (var f = function g(){}
). You absolutely need the object itself. – Crescent Fresh Commented Dec 18, 2009 at 17:09 -
2
@fredrik: I think you have some misconceptions about functions in JavaScript. What bees
this
inside the body of a function has everything to do with how the function is called and nothing to do with how it's declared. – Tim Down Commented Dec 19, 2009 at 0:58
3 Answers
Reset to default 2UPDATED *(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./showthread.php?t=134855
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 ments ;-)
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.
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.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745159712a4614334.html
评论列表(0条)