HighDots Forums  

calling a function whose name is passed as an argument

Javascript JavaScript language (comp.lang.javascript)


Discuss calling a function whose name is passed as an argument in the Javascript forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Andrew Poulos
 
Posts: n/a

Default calling a function whose name is passed as an argument - 08-11-2008 , 12:19 AM






Say I have this

foo = function() {
// blah
};

bar = fuction(fnName) {
/* If fnName equalled "foo"
* How do I test that foo, as a function,
* exists and then, if it exists, call it?
*/

// I tried testing with this
if (typeof window[fnName] != 'undefined') {
/* but a variable of the same name would
* also be true wouldn't?
*/
}
};

Andrew Poulos

Reply With Quote
  #2  
Old   
slebetman
 
Posts: n/a

Default Re: calling a function whose name is passed as an argument - 08-11-2008 , 01:18 AM






On Aug 11, 12:19 pm, Andrew Poulos <ap_p... (AT) hotmail (DOT) com> wrote:
Quote:
Say I have this

foo = function() {
// blah

};

bar = fuction(fnName) {
/* If fnName equalled "foo"
* How do I test that foo, as a function,
* exists and then, if it exists, call it?
*/
Are you REALLY passing the function by name? Most people would pass it
by reference.

Quote:
// I tried testing with this
if (typeof window[fnName] != 'undefined') {
Assuming you're passing it by reference (its unthinkable otherwise)
have you tried:

if (fn && fn instanceof Function) {
fn();
}


Reply With Quote
  #3  
Old   
Stevo
 
Posts: n/a

Default Re: calling a function whose name is passed as an argument - 08-11-2008 , 01:34 AM



slebetman wrote:
Quote:
On Aug 11, 12:19 pm, Andrew Poulos <ap_p... (AT) hotmail (DOT) com> wrote:
Say I have this

foo = function() {
// blah

};

bar = fuction(fnName) {
/* If fnName equalled "foo"
* How do I test that foo, as a function,
* exists and then, if it exists, call it?
*/

Are you REALLY passing the function by name? Most people would pass it
by reference.

// I tried testing with this
if (typeof window[fnName] != 'undefined') {

Assuming you're passing it by reference (its unthinkable otherwise)
have you tried:

if (fn && fn instanceof Function) {
fn();
}
Adapted your example for function name strings (because Andrew was very
clear about wanting to pass the function name as a string in his example):

if(window[fn] && window[fn] instanceof Function){
return window[fn]();
}

I've had to do this exact thing, but I'm not worried about the risk of
variables existing with the same name (due to some extremely unique
function names) so I just do this:

if(window[fn]) return window[fn]();


Reply With Quote
  #4  
Old   
RobG
 
Posts: n/a

Default Re: calling a function whose name is passed as an argument - 08-11-2008 , 02:20 AM



On Aug 11, 3:34*pm, Stevo <n... (AT) mail (DOT) invalid> wrote:
Quote:
slebetman wrote:
On Aug 11, 12:19 pm, Andrew Poulos <ap_p... (AT) hotmail (DOT) com> wrote:
Say I have this

foo = function() {
* *// blah

};

bar = fuction(fnName) {
* */* If fnName equalled "foo"
* * * How do I test that foo, as a function,
* * * exists and then, if it exists, call it?
* * */

Are you REALLY passing the function by name? Most people would pass it
by reference.

* *// I tried testing with this
* *if (typeof window[fnName] != 'undefined') {

Assuming you're passing it by reference (its unthinkable otherwise)
have you tried:

* if (fn && fn instanceof Function) {
* * fn();
* }

Adapted your example for function name strings (because Andrew was very
clear about wanting to pass the function name as a string in his example):

if(window[fn] && window[fn] instanceof Function){
* *return window[fn]();
}
There is a long and detailed thread about this:

<URL:
http://groups.google.com.au/group/co...aa 7cb290ec3c
Quote:

A javscript function can be defined as an object that implements an
internal [[Call]] method, i.e. that it can be called. The difficulty
is that you can't directly test for that other than actually
attempting to call it. While it is required that native functions
return true for:

typeof functionName === 'function'


there is no such requirement for host objects that can be called. For
example:

alert(typeof document.getElementById);

shows "function" in Firefox and "object" in IE, similarly:

alert( document.getElementById instanceof Function);

returns true in Firefox and false in IE.

So testing with either instanceof or typeof is only suitable if the
object to be tested is known to be a native object.


Quote:
I've had to do this exact thing, but I'm not worried about the risk of
variables existing with the same name (due to some extremely unique
function names) so I just do this:

if(window[fn]) return window[fn]();
or remove the function wrapper and use:

fn && fn();

Which is probably suitable in most cases provided adequate testing
(i.e. unit, system and acceptance) is performed and developers are
aware of the limitations.


--
Rob


Reply With Quote
  #5  
Old   
dhtml
 
Posts: n/a

Default Re: calling a function whose name is passed as an argument - 08-11-2008 , 02:02 PM



RobG wrote:
Quote:
On Aug 11, 3:34 pm, Stevo <n... (AT) mail (DOT) invalid> wrote:
slebetman wrote:
On Aug 11, 12:19 pm, Andrew Poulos <ap_p... (AT) hotmail (DOT) com> wrote:

Quote:
There is a long and detailed thread about this:

URL:
http://groups.google.com.au/group/co...aa 7cb290ec3c

I was almost going to recommend the jQuery 'isFunction' function here,
as a joke. e.g. This problem has already been solved. See
jQuery.isFunction.

Quote:
A javscript function can be defined as an object that implements an
internal [[Call]] method, i.e. that it can be called. The difficulty
is that you can't directly test for that other than actually
attempting to call it. While it is required that native functions
return true for:

typeof functionName === 'function'


Just because something is callable doesn't mean it is a function.

"is a Function" can be roughly translated to Function.prototype is on
the object's prototype chain.

To determine that, instanceof and isPrototypeOf could be used. Except
for frames, because a function in an IFRAME doesn't have the parent
window's Function.prototype in its prototype chain, so a cross-frame
test would fail.

An object that implements [[Call]] isn't necessarily a Function. That's
what David spent many long replies trying to explain to Thomas, who
seemed to not understand the intent of David's isFunction.

The purpose of knowing if something is a function, rather than is
callable, seems to be to know if you can call 'call' or 'apply' directly
on that object.

Fortunately, isFunction isn't necessary and typeof is really all you
need (see below).

Quote:
there is no such requirement for host objects that can be called. For
example:

alert(typeof document.getElementById);

shows "function" in Firefox and "object" in IE, similarly:

alert( document.getElementById instanceof Function);

returns true in Firefox and false in IE.

So testing with either instanceof or typeof is only suitable if the
object to be tested is known to be a native object.

There is no way to determine if a Host object is callable, other than to
try and call it, though that may result in Error. It would have been
better if the implementations (MSIE) had followed the spirit of the
typeof operator for Host objects. For example, in IE, getElementById is
an object that implements [[Call]].

Function.prototype.call.call(document.getElementBy Id, document, "x");

Works in IE. This could only be possible if either:

A) document.getElementById implements [[Call]].
B) JScript has a special implementation of Function.prototype.call to
handle Host object.

Either way, we can still use the callable check with the typeof operator:

if(typeof x == "function")
Function.prototype.call.call(x, context, "x");

Garrett

Quote:
--
Rob

Reply With Quote
  #6  
Old   
Thomas 'PointedEars' Lahn
 
Posts: n/a

Default Re: calling a function whose name is passed as an argument - 08-11-2008 , 02:17 PM



dhtml wrote:
Quote:
RobG wrote:
On Aug 11, 3:34 pm, Stevo <n... (AT) mail (DOT) invalid> wrote:
slebetman wrote:
On Aug 11, 12:19 pm, Andrew Poulos <ap_p... (AT) hotmail (DOT) com> wrote:

There is a long and detailed thread about this:

URL:
http://groups.google.com.au/group/co...aa 7cb290ec3c

I was almost going to recommend the jQuery 'isFunction' function here,
as a joke. e.g. This problem has already been solved. See
jQuery.isFunction.
I thought you might.

Quote:
A javscript function can be defined as an object that implements an
internal [[Call]] method, i.e. that it can be called. The difficulty
is that you can't directly test for that other than actually
attempting to call it. While it is required that native functions
return true for:

typeof functionName === 'function'

Just because something is callable doesn't mean it is a function.
And that was not what was said. However, the opposite is likely to be true.

Quote:
"is a Function" can be roughly translated to Function.prototype is on
the object's prototype chain.
Very roughly. One could also say you are mistaken here.

Quote:
To determine that, instanceof and isPrototypeOf could be used.
But that would be foolish, because (you are contradicting yourself in the
next paragraph):

Quote:
An object that implements [[Call]] isn't necessarily a Function.
It is not necessary that it is a function as long as it can be called.

Quote:
That's what David spent many long replies trying to explain to Thomas, who
seemed to not understand the intent of David's isFunction.
That is what you still do not get.

Quote:
The purpose of knowing if something is a function, rather than is
callable, seems to be to know if you can call 'call' or 'apply' directly
on that object.
True, but one would also need to determine whether the object has such
methods. Which appears to be something of a chicken-and-the-egg problem.

Quote:
Fortunately, isFunction isn't necessary and typeof is really all you
need (see below).
It is not, of course.

Quote:
there is no such requirement for host objects that can be called. For
example:

alert(typeof document.getElementById);

shows "function" in Firefox and "object" in IE, similarly:

alert( document.getElementById instanceof Function);

returns true in Firefox and false in IE.

So testing with either instanceof or typeof is only suitable if the
object to be tested is known to be a native object.

There is no way to determine if a Host object is callable, other than to
try and call it, though that may result in Error.
There you contradict yourself again.


PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm>


Reply With Quote
  #7  
Old   
Thomas 'PointedEars' Lahn
 
Posts: n/a

Default Re: calling a function whose name is passed as an argument - 08-11-2008 , 02:20 PM



Thomas 'PointedEars' Lahn wrote:
Quote:
dhtml wrote:
RobG wrote:
A javscript function can be defined as an object that implements an
internal [[Call]] method, i.e. that it can be called. The difficulty
is that you can't directly test for that other than actually
attempting to call it. While it is required that native functions
return true for:

typeof functionName === 'function'
Just because something is callable doesn't mean it is a function.

And that was not what was said. However, the opposite is likely to be true.
s/opposite/reverse/


PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f806at$ail$1$8300dec7 (AT) news (DOT) demon.co.uk>


Reply With Quote
  #8  
Old   
Dr J R Stockton
 
Posts: n/a

Default Re: calling a function whose name is passed as an argument - 08-12-2008 , 07:45 AM



In comp.lang.javascript message <g7oj23$avd$00$1 (AT) news (DOT) t-online.com>,
Mon, 11 Aug 2008 07:34:58, Stevo <no (AT) mail (DOT) invalid> posted:

Quote:
Adapted your example for function name strings (because Andrew was very
clear about wanting to pass the function name as a string in his
example):

if(window[fn] && window[fn] instanceof Function){
return window[fn]();
}
That code is not entirely satisfactory as an example. The programmer
has a clear expectation of calling a function. If the function *IS*
always considered callable by the IF, then the IF is not needed.
Otherwise, if the function is not considered callable, the programmer's
expectation is silently unfulfilled.

But the programmer's expectation is probably worthwhile; and its absence
may not always be perceived on test and may be deleterious in operation.

Therefore the IF, in the example, requires an ELSE. The example cannot
tell whether there should be a message to the user, an alternate piece
of code, or just nothing; but it can be written like

if (window[fn] && window[fn] instanceof Function) {
return window[fn]() } ; else { DealWithFailure() }

which reminds the programmer that at least some thought is needed.
Remember that examples should be aimed at the less able programmer; and
he may well be so keen on working on the "callable" case as to forget
the "non-callable" case.

--
(c) John Stockton, nr London UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ;
<URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.


Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.