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?

Community
  • 1
  • 1
brentonstrine
  • 21,694
  • 25
  • 74
  • 120

1 Answers1

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.

mknadler
  • 208
  • 1
  • 8