Skip to content

Eval: run a code string #210

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions 1-js/99-js-misc/02-eval/1-eval-calculator/solution.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Let's use `eval` to calculate the maths expression:
K výpočtu matematického výrazu použijme `eval`:

```js demo run
let expr = prompt("Type an arithmetic expression?", '2*3+2');
let výraz = prompt("Zadejte aritmetický výraz:", '2*3+2');

alert( eval(expr) );
alert( eval(výraz) );
```

The user can input any text or code though.
Uživatel však může zadat libovolný text nebo kód.

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.
Abychom všechno zabezpečili a omezili se jen na aritmetiku, můžeme zkontrolovat `výraz` pomocí [regulárního výrazu](info:regular-expressions), aby směl obsahovat jen číslice a operátory.
6 changes: 3 additions & 3 deletions 1-js/99-js-misc/02-eval/1-eval-calculator/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ importance: 4

---

# Eval-calculator
# Kalkulátor

Create a calculator that prompts for an arithmetic expression and returns its result.
Vytvořte kalkulátor, který se zeptá na aritmetický výraz a vrátí jeho výsledek.

There's no need to check the expression for correctness in this task. Just evaluate and return the result.
V této úloze není třeba ověřovat správnost výrazu. Jenom ho vyhodnoťte a vraťte výsledek.

[demo]
82 changes: 41 additions & 41 deletions 1-js/99-js-misc/02-eval/article.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
# Eval: run a code string
# Eval: spuštění řetězce kódu

The built-in `eval` function allows to execute a string of code.
Zabudovaná funkce `eval` nám umožňuje spustit řetězec kódu.

The syntax is:
Syntaxe je:

```js
let result = eval(code);
let výsledek = eval(kód);
```

For example:
Například:

```js run
let code = 'alert("Hello")';
eval(code); // Hello
let kód = 'alert("Ahoj")';
eval(kód); // Ahoj
```

A string of code may be long, contain line breaks, function declarations, variables and so on.
Řetězec kódu může být dlouhý, může obsahovat konce řádku, deklarace funkcí, proměnné a podobně.

The result of `eval` is the result of the last statement.
Výsledkem funkce `eval` je výsledek posledního příkazu.

For example:
Příklad:
```js run
let value = eval('1+1');
alert(value); // 2
let hodnota = eval('1+1');
alert(hodnota); // 2
```

```js run
let value = eval('let i = 0; ++i');
alert(value); // 1
let hodnota = eval('let i = 0; ++i');
alert(hodnota); // 1
```

The eval'ed code is executed in the current lexical environment, so it can see outer variables:
Vyhodnocovaný kód je spouštěn v aktuálním lexikálním prostředí, takže vidí vnější proměnné:

```js run no-beautify
let a = 1;
Expand All @@ -46,69 +46,69 @@ function f() {
f();
```

It can change outer variables as well:
Může vnější proměnné také měnit:

```js untrusted refresh run
let x = 5;
eval("x = 10");
alert(x); // 10, value modified
alert(x); // 10, hodnota změněna
```

In strict mode, `eval` has its own lexical environment. So functions and variables, declared inside eval, are not visible outside:
Ve striktním režimu má `eval` své vlastní lexikální prostředí, takže funkce a proměnné deklarované uvnitř `eval` nejsou viditelné zvenčí:

```js untrusted refresh run
// reminder: 'use strict' is enabled in runnable examples by default
// pamatujte: 'use strict' je ve spustitelných příkladech standardně zapnuté

eval("let x = 5; function f() {}");

alert(typeof x); // undefined (no such variable)
// function f is also not visible
alert(typeof x); // undefined (taková proměnná neexistuje)
// funkce f rovněž není viditelná
```

Without `use strict`, `eval` doesn't have its own lexical environment, so we would see `x` and `f` outside.
Bez `use strict` nemá `eval` své vlastní lexikální prostředí, takže bychom `x` a `f` venku viděli.

## Using "eval"
## Použití „eval

In modern programming `eval` is used very sparingly. It's often said that "eval is evil".
V moderním programování se `eval` používá velmi vzácně. Často se říká, že „eval je zlo“ (anglicky „eval is evil“).

The reason is simple: long, long time ago JavaScript was a much weaker language, many things could only be done with `eval`. But that time passed a decade ago.
Důvod je jednoduchý: před dávnými, dávnými časy byl JavaScript mnohem slabší jazyk a mnoho věcí bylo možné provést jedině pomocí `eval`. Ale tahle doba pominula už před deseti lety.

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 a [JavaScript Module](info:modules).
V současnosti není téměř žádný důvod, proč `eval` používat. Pokud ho někdo používá, je velká šance, že ho lze nahradit nějakým moderním jazykovým konstruktem nebo [JavaScriptovým modulem](info:modules).

Please note that its ability to access outer variables has side-effects.
Prosíme všimněte si, že jeho schopnost přistupovat k vnějším proměnným má vedlejší efekty.

Code minifiers (tools used before JS gets to production, to compress it) rename local variables into shorter ones (like `a`, `b` etc) to make the code smaller. That's usually safe, but not if `eval` is used, as local variables may be accessed from eval'ed code string. So minifiers don't do that renaming for all variables potentially visible from `eval`. That negatively affects code compression ratio.
Minifikátory kódu (nástroje používané před odesláním JS do produkce, aby jej zkomprimovaly) přejmenovávají lokální proměnné na kratší (např. `a`, `b` atd.), aby kód zkrátily. To je obvykle bezpečné, ale při použití `eval` ne, protože vyhodnocovaný řetězec kódu může k lokálním proměnným přistupovat. Minifikátory tedy u proměnných, které mohou být viditelné z `eval`, toto přejmenování neprovádějí. To negativně ovlivňuje poměr komprese kódu.

Using outer local variables inside `eval` is also considered a bad programming practice, as it makes maintaining the code more difficult.
Rovněž používání vnějších lokálních proměnných uvnitř `eval` se považuje za špatnou programátorskou praktiku, protože ztěžuje údržbu kódu.

There are two ways how to be totally safe from such problems.
Existují dva způsoby, jak být před takovými problémy zcela v bezpečí.

**If eval'ed code doesn't use outer variables, please call `eval` as `window.eval(...)`:**
**Jestliže vyhodnocovaný kód nepoužívá vnější proměnné, prosíme volejte `eval` jako `window.eval(...)`:**

This way the code is executed in the global scope:
Tímto způsobem bude kód spuštěn v globálním rozsahu platnosti:

```js untrusted refresh run
let x = 1;
{
let x = 5;
window.eval('alert(x)'); // 1 (global variable)
window.eval('alert(x)'); // 1 (globální proměnná)
}
```

**If eval'ed code needs local variables, change `eval` to `new Function` and pass them as arguments:**
**Jestliže vyhodnocovaný kód potřebuje lokální proměnné, změňte `eval` na `new Function` a předejte je jako argumenty:**

```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, also in the global scope. So it can't see local variables. But it's so much clearer to pass them explicitly as arguments, like in the example above.
Konstrukt `new Function` je vysvětlen v kapitole <info:new-function>. Vytvoří funkci z řetězce, rovněž v globálním rozsahu platnosti. Funkce tedy neuvidí lokální proměnné. Je však mnohem čistší předat je explicitně jako argumenty, tak jako v uvedeném příkladu.

## Summary
## Shrnutí

A call to `eval(code)` runs the string of code and returns the result of the last statement.
- Rarely used in modern JavaScript, as there's usually no need.
- Can access outer local variables. That's considered bad practice.
- Instead, to `eval` the code in the global scope, use `window.eval(code)`.
- Or, if your code needs some data from the outer scope, use `new Function` and pass it as arguments.
Volání `eval(kód)` spustí řetězec kódu a vrátí výsledek posledního příkazu.
- V moderním JavaScriptu se používá málokdy, jelikož obvykle není zapotřebí.
- Může přistupovat k vnějším lokálním proměnným. To se považuje za špatnou praktiku.
- K vyhodnocení kódu v globálním rozsahu platnosti místo něj použijte `window.eval(kód)`.
- Nebo, jestliže váš kód potřebuje data z vnějšího rozsahu, použijte `new Function` a předejte je jako argumenty.