1
function func1(str) {
  eval(str);
  newVar = 100;
  function func2() {
     console.log(bar);
     console.log(newVar);
  }
  func2();
}

func1("bar = 42;");

I've read that the eval() keyword should be avoiding because it cheats the lexical scope (which results in code running slower). With the context of the above example (or any other examples anybody has) i'm trying to understand what kind of compiler optimizations this might end up breaking.

Looking at the line newVar = 100; this variable too will be created by the engine (on the global scope) during the execution phase. I don't think this amounts to 'cheating' the lexical scope. Then whats the issue with eval("bar = 42;") which essentially does something similar? Hope the question is clear.

noi.m
  • 3,070
  • 5
  • 34
  • 57
  • functions can run faster if the engine knows what parts it can see and will use (ahead of time, at parse time). code not working in `"use strict"` is a good sign you're using `eval()` sub-optimally. – dandavis Mar 26 '16 at 02:34
  • What are you asking here? – amanuel2 Mar 26 '16 at 02:35
  • think of a function like a surgeon performing a procedure; if there are areas on the patient's xray that are un-clear, it's going to take longer to perform the operation while careful surgical exploration is undertaken. – dandavis Mar 26 '16 at 02:41
  • `func1("var newVar")` - A global variable isn't set. Oops. – John Dvorak Mar 26 '16 at 02:59
  • `func1("bar = top.document")` - which line conditionally throws a security error? The one with `eval` or the one one with `console.log(bar)`? – John Dvorak Mar 26 '16 at 03:01

1 Answers1

2

Because they're compiler optimizations, and the code passed to eval is almost obligatorely interpreted.

In your case the modern engines are probably smart enough to realize it's a string literal and optimize accordingly, but a new execution context is still created, and you waste a function call. Almost every single thing that an ordinary program does using eval, can be done without eval.

function func1(value)
{
  var bar = value;
  var newVar = 100;
  function func2() {
     console.log(bar);
     console.log(newVar);
  }
  func2();
}

func1(42);

EDIT: Actually, let's go deeper. On the code above, there is no possible state in which bar would be undefined when the console.log(bar); part of the code is reached. And it would always be a Number. Actually, it would always be 42. Assuming the engine has a perfect optimization algorithm, would the same hold true if the input from your eval'd code was dynamic, like for instance, coming from an AJAX reply or some form of user input? Not always. And optimizations always need to be SURE of the things they assume to cut down on final code.

henry700
  • 179
  • 3
  • 8
  • 1
    good writeup, and welcome. one nit: `optimizations always need to be SURE of the things they assume` is not true: CPU caches miss a lot, as does path tracing, but if the miscalculation is quick to detect, even usually-correct guesses can speed things up. – dandavis Mar 26 '16 at 03:10
  • Indeed, when i said "Optimizations" i was thinking about advanced type inference, and not all other optimizations. My mistake. Thank you for the welcome, clarification and first upvote ^~^ – henry700 Mar 26 '16 at 21:35