Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

eval is not a function [duplicate]

It might interest somebody and save few hours, a nasty bundling problem, eval is from one file and function is from second file.

eval('console.log(0)')
(function(x){console.log(x)})(1)

will result with: Uncaught TypeError: eval(...) is not a function

and this is the fix

eval('console.log(0)');
(function(x){console.log(x)})(1)

missing semicolon, I've read few times that semicolon in JS optional most of the time.

any comments why eval is not a function in this context?

like image 943
maciejW Avatar asked Oct 17 '25 03:10

maciejW


2 Answers

The JS runtime is not perfect at guessing where semi-colons should go.

When it sees this:

eval('console.log(0)')
(function(x){console.log(x)})(1)

It incorrectly assumes that the result of the immediately invoked function expression is part of the eval line (a potential parameter to be passed to the potential function that the eval evaluates to).

Here's an example of when that would work:

eval("(function(message){ alert(message); })")
("Hi there!");

But, in your case, eval is not evaluating to a function, so trying to pass an argument to it fails, thus your error message.

But, it actually has less to do with eval(), in particular. This can pop up anytime a semi-colon is omitted just prior to an IIFE or any expression starting with a (.

Adding the semi-colon, allows the runtime to know that the IIFE is separate.

The rule is that you must insert semi colons on any line that is followed by a ( (as this is how an expression can begin) in order to keep them separate . But, the better rule is to not rely on automatic semi-colon insertion at all and always put them in yourself.

like image 74
Scott Marcus Avatar answered Oct 19 '25 19:10

Scott Marcus


This is one of the few situations in which Javascript's semicolon insertion will trip you up.

This code:

eval('console.log(0)')
(function(x){console.log(x)})(1)

Is equivalent to this code:

eval('console.log(0)')(function(x){console.log(x)})(1)

In other words, Javascript thinks that the expression eval('console.log(0)') evaluations to a function which you are trying to call with the parameter (function(x){console.log(x)}). That is obviously not what you intended, so you need semicolons at the end of your lines.

like image 38
Lincoln Bergeson Avatar answered Oct 19 '25 19:10

Lincoln Bergeson