|
| 1 | +# Eval: run a code string |
| 2 | + |
| 3 | +The built-in `eval(code)` function allows to execute a string of `code`. |
| 4 | + |
| 5 | +For example: |
| 6 | + |
| 7 | +```js run |
| 8 | +let code = 'alert("Hello")'; |
| 9 | +eval(code); // Hello |
| 10 | +``` |
| 11 | + |
| 12 | +A call to `eval` returns the result of the last statement. |
| 13 | + |
| 14 | +For example: |
| 15 | +```js run |
| 16 | +let value = eval('1+1'); |
| 17 | +alert(value); // 2 |
| 18 | +``` |
| 19 | + |
| 20 | +The code is executed in the current lexical environment, so it can see outer variables: |
| 21 | + |
| 22 | +```js run no-beautify |
| 23 | +let a = 1; |
| 24 | + |
| 25 | +function f() { |
| 26 | + let a = 2; |
| 27 | + |
| 28 | +*!* |
| 29 | + eval('alert(a)'); // 2 |
| 30 | +*/!* |
| 31 | +} |
| 32 | + |
| 33 | +f(); |
| 34 | +``` |
| 35 | + |
| 36 | +It can change outer variables as well: |
| 37 | + |
| 38 | +```js untrusted refresh run |
| 39 | +let x = 5; |
| 40 | +eval("x = 10"); |
| 41 | +alert(x); // 10, value modified |
| 42 | +``` |
| 43 | + |
| 44 | +In strict mode, `eval` has its own lexical environment. So functions and variables, declared inside eval, are not visible outside: |
| 45 | + |
| 46 | +```js untrusted refresh run |
| 47 | +// reminder: 'use strict' is enabled in runnable examples by default |
| 48 | + |
| 49 | +eval("let x = 5; function f() {}"); |
| 50 | + |
| 51 | +alert(typeof x); // undefined (no such variable) |
| 52 | +// function f is also not visible |
| 53 | +``` |
| 54 | + |
| 55 | +Without `use strict`, `eval` doesn't have its own lexical environment, so we would see `x` and `f` outside. |
| 56 | + |
| 57 | +## Using "eval" |
| 58 | + |
| 59 | +In modern programming `eval` is used very sparingly. There's also an expression "eval is evil". |
| 60 | + |
| 61 | +The reason is simple: long, long time ago JavaScript was a weak language, many things could only be done with `eval`. But that time has passed. |
| 62 | + |
| 63 | +Right now, there's almost no reason to use `eval`. If someone is using it, there's a good chance they can replace it with a modern language construct, or [JavaScript Modules](info:modules). |
| 64 | + |
| 65 | +Still, if you're sure you need `eval`, please note that its ability to access outer variables has side-effects. |
| 66 | + |
| 67 | +Code minifiers (tools used before JS gets to production, to compress it) replace local variables with shorter ones. That's safe, unless `eval` is used. When they see `eval`, they thing it might use local variables, so they don't replace all local variables that might be visible from `eval`. That negatively affects code compression ratio. |
| 68 | + |
| 69 | +Also, renaming a local variable becomes more dangeours overall. |
| 70 | + |
| 71 | +Using outer variables inside `eval` is a bad programming practice. |
| 72 | + |
| 73 | +There are two solutions. |
| 74 | + |
| 75 | +**If you don't use outer variables, please call `eval` as `window.eval(...)`:** |
| 76 | + |
| 77 | +```js untrusted refresh run |
| 78 | +let a = 1; |
| 79 | +{ |
| 80 | + let a = 5; |
| 81 | + window.eval('alert(a)'); // 1 |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +**If your code needs variables, execute it with `new Function`:** |
| 86 | + |
| 87 | +```js run |
| 88 | +let f = new Function('a', 'alert(a)'); |
| 89 | + |
| 90 | +f(5); // 5 |
| 91 | +``` |
| 92 | + |
| 93 | +The `new Function` construct is explained in the chapter <info:new-function>. It creates a function from a string. Local variables can be passed to it as parameters, like in the example above. |
| 94 | + |
| 95 | +## Summary |
| 96 | + |
| 97 | +- A call to `eval(code)` runs the code and returns the result of the last statement. |
| 98 | +- Rarely used in modern JavaScript. |
| 99 | +- Can access outer local variables. That's considered bad practice. |
| 100 | +- To execute the code in the global scope, use `window.eval(code)`. |
| 101 | +- If your code needs some data from the outer scope, use `new Function` and pass it as arguments. |
0 commit comments