57

How can I hook up an event to a function name I have defined as a string?

I'm using Prototype.js, although this is not Prototype-speficic.

$(inputId).observe('click', formData.fields[x].onclick);

This would result in JavaScript complaining that my handler is not a function. I would prefer not us use eval().

asked Jan 30, 2009 at 19:50
1

10 Answers 10

94

Property accessors can be used to access any object's properties or functions.

If the function is in the global scope, you can get it using the window object:

var myFunc = window[myFuncName];

This also works within the this scope:

var myFunc = this[myFuncName];
Ryenski
9,7124 gold badges46 silver badges49 bronze badges
answered Jan 30, 2009 at 19:53
Sign up to request clarification or add additional context in comments.

3 Comments

...or scope[myFuncName] in general
Yup, as long as you have a handle to the scope somewhere, this'll work
Is there a way to do this in a Node.js module?
9

I have worked on this problem, as I needed a function like this. Here is my sandbox code, not thoroughly tested, but can be a startpoint for others. Note that there is one eval() in the code as I couldn't figure out how to bypass that step, maybe a javascript quirk and cannot be done in any other way. Let me know if there is a way to get rid of eval() here!

executeFunctionByName = function(functionName)
{
 var args = Array.prototype.slice.call(arguments).splice(1);
 //debug
 console.log('args:', args);
 var namespaces = functionName.split(".");
 //debug
 console.log('namespaces:', namespaces);
 var func = namespaces.pop();
 //debug
 console.log('func:', func);
 ns = namespaces.join('.');
 //debug
 console.log('namespace:', ns);
 if(ns == '')
 {
 ns = 'window';
 }
 ns = eval(ns);
 //debug
 console.log('evaled namespace:', ns);
 return ns[func].apply(ns, args);
}
core = {
 paragraph: {
 titlebar: {
 user: "ddd",
 getUser: function(name)
 {
 this.user = name;
 return this.user;
 }
 }
 }
}
var testf = function()
{
 alert('dkdkdkd');
}
var x = executeFunctionByName('core.paragraph.titlebar.getUser', 'Ikon');
executeFunctionByName('testf');
answered Oct 26, 2010 at 11:19

2 Comments

To get rid of the eval you could navigate the namespaces from the window object: var func = window; for(var i=0;i<namespaces.length;++i){ func = func[namespaces[i]]; }
Thanks Ikon. I tried many ways, this answer will solve my problem.
8

... or this[myFuncName];

answered Jan 30, 2009 at 19:57

Comments

6

Perhaps?

setTimeout ( "myFunc()", 1 );
answered Nov 9, 2011 at 10:51

Comments

5

Just an eval would do the job

var call = eval("method_name").call(args);
Devraj Gadhavi
3,6613 gold badges40 silver badges70 bronze badges
answered Mar 28, 2013 at 16:33

1 Comment

Great! this worked... thanks; You forgot . in between. var call = eval("mathod_name").call(args);
3

Looks like formData.fields[x].onclick holds the name of a global function? If so try:

$(inputId).observe('click', window[formData.fields[x].onclick]);
answered Jan 30, 2009 at 19:58

Comments

3
window.myFunction === window["myFunction"]
yojimbo87
68.8k26 gold badges128 silver badges133 bronze badges
answered Jan 30, 2009 at 19:54

Comments

1

Do you know what the onclick property contains or what type it is? I assume this is prototype specific stuff, as "fields" does not exist in DOM forms.

answered Jan 31, 2009 at 23:33

Comments

1

update:--- use ES6 export and import

a.js

const fn = {
 aaa: function() {
 //code
 },
 bbb: function() {
 //code
 },
 //codes ....
 nnn: function() {
 //code
 }
}
export default fn

b.js

 import someFn from './a'
 //eg
 const str1='aaa'
 const str2 = 'bbb'
 someFn[str1]()

These methods above always not be recommend by some reasons, but they are really convenient to use. These methods below are safe, but really not conveninet to use.

  • switch...case (or if...else)

    switch(str){
     case 'str1': 
     fn1()
     break
     case 'str2':
     fn2
     //and so on
    }
    
  • put functions in a object

    const fn={
     str1:fn1,
     str2:fn2
     //and so on
    }
    fn[str1] //call function
    
answered Dec 10, 2017 at 9:15

Comments

0

If you need to call a string function with arguments, do this:

window[stringFunctionName].apply( window, arrayOfArguments )

You can use scope in place of window if preferred

answered Sep 19, 2014 at 11:47

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.