javascript - What's wrong with `var myEval = eval; myEval("2+2")` -


as per mdn-eval

you cannot indirectly use eval function invoking via name other eval(); if do, runtime error might occur. example, should not use following code:

var x = 2; //1 var y = 4; //2 var myeval = eval; //3 eval("x + y"); //4 myeval("x + y"); //5 

normal cases javascript not have minded var somereference = somefunctionreference; yes eval special case can expect surprises.

now let's see of following runs in non-strict mode

  1. firefox/aurora(v39.0) not mind , above code runs well.
  2. chrome(v 42.0.2311.135 m) v8 4.2.77.18 runs well. (v8 version taken chrome://version/)
  3. node(v0.10.35) v8 3.14.5.9 complains error x undefined @ line number 5 (v8 version taken node -e "console.log(process.versions.v8)")

now query why there different behavior , how/when doing coding style brings risk program.

p.s.: line //4 not complain error in of run , assumption in above runs chrome/firefox console run in non-strict mode.

eval special. of es5 (~2009), direct call eval works within current scope, indirect call myeval works in global scope. detailed in §10.4.2 , §15.1.2.1.1.

so if code being run within function, e.g.:

function foo() {     var x = 2;     var y = 4;     var myeval = eval;     myeval("x + y"); } 

...then correct behavior of es5 complain x not exist.

if code @ global scope outside of functions, e.g.:

var x = 2; var y = 4; var myeval = eval; myeval("x + y"); 

...then correct behavior result 6. full example below.

now query why there different behavior...

if running code in browser console, may down console implementation (e.g., 1 console may evaluate code within function, globally). console special environment, scope-related things best tested normal page.

and how/when doing coding style brings risk program.

there's no significant difference in risk using eval directly or indirectly. risk comes using eval (at all) on input don't control. if you're taking input user , running on computer, risk them. however, if you're taking input 1 user, later running via eval on another user's computer or on server, that's significant risk: you're allowing user reach out , run code on machine isn't theirs.

p.s.: assumption in above runs chrome/firefox console run in non-strict mode.

strict mode doesn't affect aspect of eval. (it does affect other aspects of it, in particular whether can create variables within local scope [it can in loose mode, can't in strict mode]; that's in §10.4.2.)


live example:

function direct() {    var x = 2;    var y = 4;    return eval("x + y");  }    function indirect() {    var x = 2;    var y = 4;    var myeval = eval;    return myeval("x + y");  }    snippet.log("direct (within function):");  try {    snippet.log("got " + direct());  }  catch (e) {    snippet.log("got exception: " + e.message);  }    snippet.log("indirect (within function):");  try {    snippet.log("got " + indirect());  }  catch (e) {    snippet.log("got exception: " + e.message);  }    var globalx = 2;  var globaly = 4;    snippet.log("direct (at global scope):");  try {    snippet.log("got " + eval("globalx + globaly"));  }  catch (e) {    snippet.log("got exception: " + e.message);  }    snippet.log("indirect (at global scope):");  var myglobaleval = eval;  try {    snippet.log("got " + myglobaleval("globalx + globaly"));  }  catch (e) {    snippet.log("got exception: " + e.message);  }
<!-- script provides `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->  <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

correct behavior show:

 direct (within function): got 6 indirect (within function): got exception: x not defined direct (at global scope): got 6 indirect (at global scope): got 6 

Comments