Eval:spustit řetězec kódu

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žijte window.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.