eval
This commit is contained in:
parent
42a1108f8c
commit
329a53c6a9
4 changed files with 124 additions and 1 deletions
|
@ -15,7 +15,7 @@ If you haven't selected an IDE yet, consider the following options:
|
||||||
- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free).
|
- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free).
|
||||||
- [WebStorm](http://www.jetbrains.com/webstorm/) (cross-platform, paid).
|
- [WebStorm](http://www.jetbrains.com/webstorm/) (cross-platform, paid).
|
||||||
|
|
||||||
For Windows, there's also "Visual Studio", not to be confused with "Visual Studio Code". "Visual Studio" is a paid and mighty Windows-only editor, well-suited for the .NET platform. It's also good at JavaScript.
|
For Windows, there's also "Visual Studio", not to be confused with "Visual Studio Code". "Visual Studio" is a paid and mighty Windows-only editor, well-suited for the .NET platform. It's also good at JavaScript. There's also a free version [Visual Studio Community](https://www.visualstudio.com/vs/community/).
|
||||||
|
|
||||||
Many IDEs are paid, but have a trial period. Their cost is usually negligible compared to a qualified developer's salary, so just choose the best one for you.
|
Many IDEs are paid, but have a trial period. Their cost is usually negligible compared to a qualified developer's salary, so just choose the best one for you.
|
||||||
|
|
||||||
|
|
11
10-misc/02-eval/1-eval-calculator/solution.md
Normal file
11
10-misc/02-eval/1-eval-calculator/solution.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Let's use `eval` to calculate the maths expression:
|
||||||
|
|
||||||
|
```js demo run
|
||||||
|
let expr = prompt("Type an arithmetic expression?", '2*3+2');
|
||||||
|
|
||||||
|
alert( eval(expr) );
|
||||||
|
```
|
||||||
|
|
||||||
|
The user can input any text or code though.
|
||||||
|
|
||||||
|
To make things safe, and limit it to arithmetics only, we can check the `expr` using a [regular expression](info:regular-expressions), so that it only may contain digits and operators.
|
11
10-misc/02-eval/1-eval-calculator/task.md
Normal file
11
10-misc/02-eval/1-eval-calculator/task.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
importance: 4
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Eval-calculator
|
||||||
|
|
||||||
|
Create a calculator that prompts for an arithmetic expression and returns its result.
|
||||||
|
|
||||||
|
There's no need to check the expression for correctness in this task.
|
||||||
|
|
||||||
|
[demo]
|
101
10-misc/02-eval/article.md
Normal file
101
10-misc/02-eval/article.md
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
# Eval: run a code string
|
||||||
|
|
||||||
|
The built-in `eval(code)` function allows to execute a string of `code`.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```js run
|
||||||
|
let code = 'alert("Hello")';
|
||||||
|
eval(code); // Hello
|
||||||
|
```
|
||||||
|
|
||||||
|
A call to `eval` returns the result of the last statement.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
```js run
|
||||||
|
let value = eval('1+1');
|
||||||
|
alert(value); // 2
|
||||||
|
```
|
||||||
|
|
||||||
|
The code is executed in the current lexical environment, so it can see outer variables:
|
||||||
|
|
||||||
|
```js run no-beautify
|
||||||
|
let a = 1;
|
||||||
|
|
||||||
|
function f() {
|
||||||
|
let a = 2;
|
||||||
|
|
||||||
|
*!*
|
||||||
|
eval('alert(a)'); // 2
|
||||||
|
*/!*
|
||||||
|
}
|
||||||
|
|
||||||
|
f();
|
||||||
|
```
|
||||||
|
|
||||||
|
It can change outer variables as well:
|
||||||
|
|
||||||
|
```js untrusted refresh run
|
||||||
|
let x = 5;
|
||||||
|
eval("x = 10");
|
||||||
|
alert(x); // 10, value modified
|
||||||
|
```
|
||||||
|
|
||||||
|
In strict mode, `eval` has its own lexical environment. So functions and variables, declared inside eval, are not visible outside:
|
||||||
|
|
||||||
|
```js untrusted refresh run
|
||||||
|
// reminder: 'use strict' is enabled in runnable examples by default
|
||||||
|
|
||||||
|
eval("let x = 5; function f() {}");
|
||||||
|
|
||||||
|
alert(typeof x); // undefined (no such variable)
|
||||||
|
// function f is also not visible
|
||||||
|
```
|
||||||
|
|
||||||
|
Without `use strict`, `eval` doesn't have its own lexical environment, so we would see `x` and `f` outside.
|
||||||
|
|
||||||
|
## Using "eval"
|
||||||
|
|
||||||
|
In modern programming `eval` is used very sparingly. There's also an expression "eval is evil".
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
Still, if you're sure you need `eval`, please note that its ability to access outer variables has side-effects.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Also, renaming a local variable becomes more dangeours overall.
|
||||||
|
|
||||||
|
Using outer variables inside `eval` is a bad programming practice.
|
||||||
|
|
||||||
|
There are two solutions.
|
||||||
|
|
||||||
|
**If you don't use outer variables, please call `eval` as `window.eval(...)`:**
|
||||||
|
|
||||||
|
```js untrusted refresh run
|
||||||
|
let a = 1;
|
||||||
|
{
|
||||||
|
let a = 5;
|
||||||
|
window.eval('alert(a)'); // 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**If your code needs variables, execute it with `new Function`:**
|
||||||
|
|
||||||
|
```js run
|
||||||
|
let f = new Function('a', 'alert(a)');
|
||||||
|
|
||||||
|
f(5); // 5
|
||||||
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
- A call to `eval(code)` runs the code and returns the result of the last statement.
|
||||||
|
- Rarely used in modern JavaScript.
|
||||||
|
- Can access outer local variables. That's considered bad practice.
|
||||||
|
- To execute the code in the global scope, use `window.eval(code)`.
|
||||||
|
- If your code needs some data from the outer scope, use `new Function` and pass it as arguments.
|
Loading…
Add table
Add a link
Reference in a new issue