JavaScript: eval vs Function


eval evaluates an expression:

eval('2 + 2'); // 4

What if there’s more than one expression?

eval('2 + 2; "foo"'); // "foo"

It returns the value of the last expression.

However, eval is considered to be evil because:

  1. it’s run in the scope that it’s invoked and
  2. it’s not known to be performant.

Here’s an example of eval evaluating an overridden undefined variable:

function evalInScope() {
  var undefined = 'foo';
  return eval('undefined');
}

evalInScope(); // "foo"
undefined; // undefined

So what can we do about this?

Luckily, we have Function as a better alternative:

var func = new Function('return 2 + 2');
func(); // 4

And what about the execution context?

function funcInScope() {
  var undefined = 'foo';
  return new Function('return undefined')();
}

funcInScope(); // undefined

It looks like the function is evaluated in a separate scope.

A helper can be created for maximum portability:

function execute(code) {
  // this is the recommended way of executing code with Function
  return Function('"use strict";return ' + code)();
}

And to invoke our function with a particular context, we can use call or apply:

var myContext = { works: true };
Function('return this.works').call(myContext); // true