1

I'm trying to execute a function using a string containing the functions name.

Several resources I've found suggest something like this:

function runMe(){alert("fail"));
var fnstring = "runMe";
var fn = window[fnstring];
fn();

However, it doesn't work at all for me (JSFiddle demo). I end up with fn as undefined. Am I doing something wrong, or has window behavior changed?

9
  • Is runMe function defined in a global scope? "using a string containing the functions name" --- any chance to reconsider this "design"? It smells. Commented Aug 6, 2014 at 22:53
  • Hm, I'm not quite sure how jsfiddle works... maybe not... Commented Aug 6, 2014 at 22:54
  • 1
    by default it's not. Switch to No wrap - in body in the left 2nd dropdown. Commented Aug 6, 2014 at 22:55
  • Dah, ok that was it, thanks! Commented Aug 6, 2014 at 23:01
  • Ok, now I've got it working (with arguments) in JSFiddle, but when I paste it into a <script></script> in the body of my dev page, it breaks with error: "Uncaught TypeError: undefined is not a function". Commented Aug 6, 2014 at 23:14

1 Answer 1

1

You're getting the Uncaught TypeError: undefined is not a function error because of hoisting. Looking at the first link you provided, there was one key difference between your version and theirs: the conditional.

Your (second) version:

function runMe(thething) {
    alert("the function has successfully run: " + thething);
}

// function we want to run
var fnstring = "runMe";
alert("string: " + fnstring);

// find object
var fn = window[fnstring]("lkjlksdfsdfj");
alert("function: " + fn);

// is object a function?
alert("is function?: " + typeof fn === "function");
fn();

My version, working without errors:

function runMe(thething) {
    console.log("the function has successfully run: " + thething);
}

// function we want to run
var fnstring = "runMe";

// find object
var fn = window[fnstring]("lkjlksdfsdfj");

// is object a function?
if (typeof fn === "function") fn();

The reason why your version throws an error is that it is being hoisted into something like this:

function runMe(thething) {
    alert("the function has successfully run: " + thething);
}

var fnstring, fn;

fn();

fnstring = "runMe";
fn = window[fnstring]("lkjlksdfsdfj");

So when it's called it isn't a function; it's an undefined variable.

On the other hand, as far as I understand hoisting, my version gets hoisted something like this:

function runMe(thething) {
    console.log("the function has successfully run: " + thething);
}

var fnstring, fn;
fnstring =  = "runMe";
fn = window[fnstring]("lkjlksdfsdfj");

if (typeof fn === "function") fn();

So that by the time the function is actually called, everything's good to go.

Sign up to request clarification or add additional context in comments.

2 Comments

Ah, thanks. Man, I really need to get more familiar with how hoisting works. Cheers!
Yeah, it's the source of SO many issues I run into that seem to be coming "out of nowhere".

Your Answer

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.