Skip to content
Advertisement

Eval a function definition vs. variable function definition

If we define a function f() { ... } in eval(...), why isn’t it available for the rest of the code, such as #button3’s onclick?

As a comparison, if we define the function as f = () => { ... };, then it is available for #button3’s onclick.

Why this difference, which seems a little bit contradictory with var functionName = function() {} vs function functionName() {} (here the idea is function f() { ... } has a wider scope than f = () => { ... };).

Click 1 and 3 (Uncaught ReferenceError: f is not defined), and then 2 and 3 (working):

JavaScript
JavaScript

Advertisement

Answer

As MDN says on eval:

var-declared variables and function declarations would go into the surrounding scope if the source string is not interpreted in strict mode — for indirect eval, they become global variables. If it’s a direct eval in a strict mode context, or if the eval source string itself is in strict mode, then var and function declarations do not “leak” into the surrounding scope.

Here, you’re using direct eval (because you’re referencing eval) directly, and that “surrounding scope” is the inside of the click handler. To see this working, click, then see how the function f approach defines an f referenceable later in the click handler (but not outside of it):

JavaScript
JavaScript

Doing

JavaScript

is just like doing that in plain code, without eval – without declaring it with const, let, var, or function, you’re implicitly assigning to the global object, so

JavaScript

is equivalent to

JavaScript

if no f variable exists in scope at that time.

JavaScript

Inline handlers may only reference global variables (99% of the time), so for onclick="f();" to work, window.f must exist.

You’re using direct eval. Note that if you used indirect eval, the evaled code won’t run in the scope of where the eval reference was called, but rather on the top level – and as a result, any variable declaration inside such an eval will be visible everywhere.

JavaScript
JavaScript
Advertisement