Search code examples
javascriptfunctioneval

Eval not declaring functions


I have a code string I'm given that's already created for me elsewhere, using Blockly. It looks to me like it's correct, when I echo it straight out to a page:

function someName(){
    //some code
}
//more code
someName();

However, when I call eval on it, the function call itself does not work. It claims the function is not defined. Everything but the function declarations is working. The code string itself is set, and I can't change it unless I do a lot of parsing. Is there some simpler way to get these functions declared so the code can call them?

Test case (that I actually used):

function test(){
    alert("This is a test");
}
test();

Solution

  • eval works within a very special environment which is in many ways a lot like local scope. So if you're calling eval on that string within a function, the someName function will only be declared within that function, e.g.:

    function doSomething(str) {
      eval(str);
      snippet.log(typeof someName); // "function"
    }
    doSomething("function someName() { }");
    snippet.log(typeof someName); // "undefined"
    <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

    If you want it declared globally, you have to do some work. Kangax wrote up an excellent discussion of the options for "global eval". One of the options is the one David Flanagan suggested:

    var geval = this.execScript || eval;
    

    Then use geval. This works because IE has execScript, which works at global scope, and in other browsers calling eval indirectly through a variable referring to it makes it work at global scope as well. But read the article for more details and options.

    function doSomething(str) {
      var geval = this.execScript || eval;
      geval(str);
      snippet.log(typeof someName); // "function"
    }
    doSomething("function someName() { }");
    snippet.log(typeof someName); // "function"
    <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>