eval(), new Function() (fortgeschritten)eval()new Function()In diesem Kapitel befassen wir uns mit zwei Möglichkeiten der dynamischen Codeauswertung: eval() und new Function().
eval()Gegeben eine Zeichenkette str mit JavaScript-Code, wertet eval(str) diesen Code aus und gibt das Ergebnis zurück.
> eval('2 ** 4')
16Es gibt zwei Möglichkeiten, eval() aufzurufen:
„Nicht über einen Funktionsaufruf“ bedeutet „alles, was anders aussieht als eval(···)“.
eval.call(undefined, '···') (verwendet die Methode .call() von Funktionen)eval?.() () (verwendet optionales Chaining)(0, eval)('···') (verwendet den Komma-Operator)globalThis.eval('···')const e = eval; e('···')Der folgende Code veranschaulicht den Unterschied.
globalThis.myVariable = 'global';
function func() {
const myVariable = 'local';
// Direct eval
assert.equal(eval('myVariable'), 'local');
// Indirect eval
assert.equal(eval.call(undefined, 'myVariable'), 'global');
}Die Auswertung von Code im globalen Kontext ist sicherer, da der Code Zugriff auf weniger Interna hat.
new Function()new Function() erstellt ein Funktions-Objekt und wird wie folgt aufgerufen:
const func = new Function('«param_1»', ···, '«param_n»', '«func_body»');Die vorherige Anweisung ist äquivalent zur nächsten Anweisung. Beachten Sie, dass «param_1» usw. nicht mehr innerhalb von Zeichenkettenliteralen stehen.
const func = function («param_1», ···, «param_n») {
«func_body»
};Im nächsten Beispiel erstellen wir dieselbe Funktion zweimal, zuerst über new Function(), dann über einen Funktionsausdruck.
const times1 = new Function('a', 'b', 'return a * b');
const times2 = function (a, b) { return a * b };
new Function() erstellt Funktionen im non-strict mode
Standardmäßig sind Funktionen, die über new Function() erstellt werden, sloppy. Wenn wir möchten, dass der Funktionskörper im strict mode ausgeführt wird, müssen wir ihn manuell aktivieren.
Vermeiden Sie die dynamische Auswertung von Code so weit wie möglich.
Sehr oft ist JavaScript dynamisch genug, sodass Sie eval() oder Ähnliches nicht benötigen. Im folgenden Beispiel kann das, was wir mit eval() tun (Zeile A), genauso gut ohne es erreicht werden (Zeile B).
const obj = {a: 1, b: 2};
const propKey = 'b';
assert.equal(eval('obj.' + propKey), 2); // (A)
assert.equal(obj[propKey], 2); // (B)Wenn Sie Code dynamisch auswerten müssen:
new Function() gegenüber eval(): Es führt seinen Code immer im globalen Kontext aus und eine Funktion bietet eine saubere Schnittstelle zum ausgewerteten Code.eval gegenüber direktem eval: Die Auswertung von Code im globalen Kontext ist sicherer.