Vestavěný eval
funkce umožňuje spustit řetězec kódu.
Syntaxe je:
let result = eval(code);
Například:
let code = 'alert("Hello")';
eval(code); // Hello
Řetězec kódu může být dlouhý, může obsahovat zalomení řádků, deklarace funkcí, proměnné a tak dále.
Výsledek eval
je výsledkem posledního příkazu.
Například:
let value = eval('1+1');
alert(value); // 2
let value = eval('let i = 0; ++i');
alert(value); // 1
Vyhodnocený kód je spuštěn v aktuálním lexikálním prostředí, takže může vidět vnější proměnné:
let a = 1;
function f() {
let a = 2;
eval('alert(a)'); // 2
}
f();
Může také měnit vnější proměnné:
let x = 5;
eval("x = 10");
alert(x); // 10, value modified
V přísném režimu eval
má své vlastní lexikální prostředí. Takže funkce a proměnné, deklarované uvnitř eval, nejsou viditelné vně:
// 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
Bez use strict
, eval
nemá své vlastní lexikální prostředí, takže bychom viděli x
a f
venku.
Pomocí „eval“
V moderním programování eval
se používá velmi střídmě. Často se říká, že „eval je zlo“.
Důvod je prostý:dávno, velmi dávno byl JavaScript mnohem slabší jazyk, mnoho věcí bylo možné dělat pouze s eval
. Ale ta doba uplynula před deseti lety.
Právě teď není téměř žádný důvod používat eval
. Pokud jej někdo používá, je velká šance, že jej nahradí moderní jazykovou konstrukcí nebo modulem JavaScript.
Vezměte prosím na vědomí, že jeho schopnost přístupu k vnějším proměnným má vedlejší účinky.
Minifikátory kódu (nástroje používané předtím, než se JS dostane do produkce, pro jeho kompresi) přejmenovávají místní proměnné na kratší (jako a
, b
atd.), aby byl kód menší. To je obvykle bezpečné, ale ne pokud eval
se používá, protože k místním proměnným lze přistupovat z vyhodnoceného kódového řetězce. Minifikátory tedy nepřejmenovávají všechny proměnné potenciálně viditelné z eval
. To negativně ovlivňuje poměr komprese kódu.
Použití vnějších lokálních proměnných uvnitř eval
je také považován za špatnou programátorskou praxi, protože ztěžuje údržbu kódu.
Existují dva způsoby, jak být před takovými problémy zcela v bezpečí.
Pokud hodnocený kód nepoužívá vnější proměnné, zavolejte na číslo eval
jako window.eval(...)
:
Tímto způsobem je kód spuštěn v globálním rozsahu:
let x = 1;
{
let x = 5;
window.eval('alert(x)'); // 1 (global variable)
}
Pokud vyhodnocovaný kód potřebuje místní proměnné, změňte eval
na new Function
a předat je jako argumenty:
let f = new Function('a', 'alert(a)');
f(5); // 5
new Function
konstrukt je vysvětlen v kapitole Syntaxe "nové funkce". Vytváří funkci z řetězce, také v globálním rozsahu. Nemůže tedy vidět místní proměnné. Ale je mnohem jasnější je předat explicitně jako argumenty, jako v příkladu výše.
Shrnutí
Volání na číslo eval(code)
spustí řetězec kódu a vrátí výsledek posledního příkazu.
- V moderním JavaScriptu se používá zřídka, protože obvykle není potřeba.
- Má přístup k vnějším lokálním proměnným. To je považováno za špatný postup.
- Namísto toho na
eval
kód v globálním rozsahu, použijtewindow.eval(code)
. - Nebo, pokud váš kód potřebuje nějaká data z vnějšího rozsahu, použijte
new Function
a předat to jako argumenty.