Читать книгу JavaScript – Das Handbuch für die Praxis - David Flanagan - Страница 108

4.12.2Globales eval()

Оглавление

eval() ist für den JavaScript-Optimierer deshalb so problematisch, weil es lokale Variablen ändern kann. Um das zu umgehen, führen Interpreter bei Funktionen, die eval() aufrufen, einfach weniger Optimierungen aus. Aber was soll ein JavaScript-Interpreter tun, wenn ein Skript ein Alias für eval() definiert und die Funktion einfach unter einem anderen Namen aufruft? Die JavaScript-Spezifikation sieht vor, dass bei einem Aufruf von eval() unter einem anderen Namen die Zeichenkette so ausgewertet werden soll, als würde es sich um globalen Code der höchsten Programmebene handeln. Der ausgewertete Code darf neue globale Variablen oder Funktionen deklarieren und globale Variablen erstellen, darf aber in der aufrufenden Funktion keine Variablen mehr nutzen oder verändern und kommt so den lokalen Optimierungen nicht mehr ins Gehege.

Ein »direktes Eval« ist ein Aufruf der eval()-Funktion mit einem Ausdruck, der den genauen, nicht qualifizierten Namen »eval« verwendet (der damit immer mehr wie ein reserviertes Wort wirkt). Direkte Aufrufe von eval() nutzen die Variablenumgebung des aufrufenden Kontexts. Jeder andere – indirekte – Aufruf nutzt als Variablenumgebung das globale Objekt und kann lokale Variablen oder Funktionen weder lesen noch schreiben noch definieren. (Sowohl direkte als auch indirekte Aufrufe können neue Variablen nur mit var definieren. Die Verwendung von let und const innerhalb einer auszuwertenden Zeichenkette erzeugt Variablen und Konstanten, die lokal zur Auswertung gehören und die aufrufende oder globale Umgebung nicht verändern.)

Der folgende Code verdeutlicht dies:

const geval = eval; // Die Verwendung eines anderen Namens führt zu

// einem globalen Eval.

let x = "global", y = "global"; // Zwei globale Variablen.

function f() { // Diese Funktion führt ein lokales Eval aus.

let x = "local"; // Eine lokale Variable definieren.

eval("x += 'changed';"); // Das direkte Eval setzt die lokale Variable.

return x; // Den geänderten lokalen Wert zurückliefern.

}

function g() { // Diese Funktion führt ein globales Eval aus.

let y = "local"; // Eine lokale Variable.

geval("y += 'changed';"); // Ein indirektes Eval setzt die globale

// Variable.

return y; // Liefert den unveränderten lokalen Wert.

}

console.log(f(), x); // Lokale Variable geändert: ergibt "localchanged global".

console.log(g(), y); // Globale Variable geändert: ergibt "local globalchanged".

Die Möglichkeit, ein globales Eval durchzuführen, ist übrigens mehr als eine Anpassung an die Anforderungen des Optimierers. Das globale Eval ist tatsächlich eine unglaublich nützliche Einrichtung, mit der man Strings mit Code ausführen kann, als enthielten sie unabhängige Skripte der obersten Ebene. Wie bereits zu Anfang dieses Abschnitts erwähnt, kommt es nur äußerst selten vor, dass man Strings mit Code auswerten muss. Wenn Sie aber das Gefühl haben, es sei notwendig, ist meist ein globales Eval die bessere Lösung als ein lokales.

JavaScript  –  Das Handbuch für die Praxis

Подняться наверх