javascript - Using eval to execute functions - Stack Overflow

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

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

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

And then I write

eval("foo()");

or

eval("foo" + "();");

The function foo is executed and I have "test" printed out. However, if I write:

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

or

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

I get "SyntaxError: Unexpected token )". Why is that? I saw that when I pass the function name it is evaluated into the function's code, so I though it's supposed to be the same as "eval("foo" + "();");"

I'm using Chrome 27 if it makes any difference.

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

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

And then I write

eval("foo()");

or

eval("foo" + "();");

The function foo is executed and I have "test" printed out. However, if I write:

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

or

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

I get "SyntaxError: Unexpected token )". Why is that? I saw that when I pass the function name it is evaluated into the function's code, so I though it's supposed to be the same as "eval("foo" + "();");"

I'm using Chrome 27 if it makes any difference.

Share Improve this question asked Jul 3, 2013 at 11:54 BennyzBennyz 6232 gold badges18 silver badges36 bronze badges 3
  • 2 eval is meant to evaluate expressions, the last example isn't a single expression. Add an operator to the function declaration and you're there. That said eval-ing code like this is a terrible idea, so I'd suggest not to even begin to try and understand how it works – Elias Van Ootegem Commented Jul 3, 2013 at 12:01
  • actually, eval is totally irrelevant here - that code will fail just in the same way without it. – georg Commented Jul 3, 2013 at 12:38
  • @thg435: Yes, it will. In my answer I went into more detail, and explained why his last eval call actually contained a syntactically invalid statement – Elias Van Ootegem Commented Jul 3, 2013 at 12:47
Add a ment  | 

6 Answers 6

Reset to default 4

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 pute, 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

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. :)

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

This is called a self-executing anonymous function.

you would need to call

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

in order for this to work;

Put brackets around your function

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

It is like calling

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

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.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744166184a4561313.html

相关推荐

  • javascript - Using eval to execute functions - Stack Overflow

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

    8天前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信