Using eval to execute functions

前端 未结 6 1206
太阳男子
太阳男子 2020-12-21 20:18

There is something I don\'t understand about how eval works. Suppose I have a function foo:

function foo() {
    console.log(\"test\");
}

A

相关标签:
6条回答
  • 2020-12-21 20:25
    eval("(function() { console.log(\"foo\"); })()");
    

    This is called a self-executing anonymous function.

    0 讨论(0)
  • 2020-12-21 20:25

    Put brackets around your function

    eval("(function foo() { console.log(\"foo\"); })()");
    

    It is like calling

    (function foo() { console.log("foo"); })()
    
    0 讨论(0)
  • 2020-12-21 20:26

    function x() {} is a statement, whereas everything else you're doing is an expression, and you can only evaluate expressions.

    The other answers explain how you can turn this statement into an expression. Thought I'd let you know why you actually get an error, though. :)

    0 讨论(0)
  • 2020-12-21 20:42

    you would need to call

    eval("function foo() { console.log(\"foo\"); };" + " foo();");
    

    in order for this to work;

    0 讨论(0)
  • 2020-12-21 20:44

    The main thing you should understand about eval is that it is evil. Don't use it... ever. There is always a way to achieve the same thing by dynamically creating a script document or by using a closure.

    Read Douglas Crockford: JavaScript the good parts.

    0 讨论(0)
  • 2020-12-21 20:48

    Because no answer is specific about why the last snippet fails, and nobody seems to be warning you for the dangers of eval:

    eval, according to MDN:

    A string representing a JavaScript expression, statement, or sequence of statements. The expression can include variables and properties of existing objects.

    Your string, "function foo(){console.log('foo');}()" actually consists of 2 statements, that make no sense to the JS engine. Well, the second one doesn't:

    function foo(){console.log('foo');}//function declaration, fine
    ;//<-- js adds implied statement terminator
    ()//no invocation, because no function reference, group nothing ==> does not compute, raise error
    

    That's why you have to turn your function declaration statement into an expression, by adding an operator. Typically, this is the grouping operator: ()

    (function foo(){ console.log('foo')});
    

    The function declaration is now an expression, everything (the grouping () included) can be seen as a statement, unless the code that follows belongs to the code above. In this case, the invoking parentheses clearly do, so the JS engine sorts it out for you.
    For clarity, some say the preferred notation is:

    (function f(){}());//<-- invoking parentheses inside group
    

    Which makes sense, because the invocation is part of the statement, after all.

    If you don't like all these parentheses, any operator will do:

    ~function(){}();//bitwise not
    +function(){}();//coerce to number
    

    Are all equally valid. Note that they will change the possible return values of the function expression.

    (function(){}());//resolves to undefined
    +function(){}();//resolves to NaN, because undefined is NotANumber
    

    How your eval could look, then, is any of the following:

    eval("(function (){console.log('foo');}());");
    eval("~function (){console.log('foo');}();");
    eval("!function (){console.log('foo');}();");
    

    And so on, and so forth...

    Lastly, eval evaluates code in the global scope, so any code eval-ed containing functions can, and likely will, polute the global namespace. Mallicious code will also have access to everything, so be weary of XSS attacks and all other JS based techniques.
    Bottom line, eval is evil, especially since all browsers now support JSON.parse natively, and for those that don't, there still is a tried and tested JSON2.js file out there.
    Using eval in strict mode does make things slightly safer, but doesn't prevent XSS attacks at all, the code can still manipulate the DOM, for example, and reassign exposed DOM references or objects.

    Google "why eval is evil" if you want to find out more.
    Also check the ECMAScript specs

    0 讨论(0)
提交回复
热议问题