Tun diese beiden Funktionen hinter den Kulissen dasselbe? (in Einzelanweisungsfunktionen)
var evaluate = function(string) {
return eval('(' + string + ')');
}
var func = function(string) {
return (new Function( 'return (' + string + ')' )());
}
console.log(evaluate('2 + 1'));
console.log(func('2 + 1'));
javascript
function
optimization
eval
qwertymk
quelle
quelle
new
in dieser Diskussion berücksichtigt?Function
implizit instanziiert afunction object
. Durch das Ausschließennew
wird der Code überhaupt nicht geändert. Hier ist eine jsfiddle, die das demonstriert: jsfiddle.net/PcfG8Antworten:
Nein, sie sind nicht gleich.
eval()
wertet eine Zeichenfolge als JavaScript-Ausdruck im aktuellen Ausführungsbereich aus und kann auf lokale Variablen zugreifen.new Function()
analysiert den in einer Zeichenfolge gespeicherten JavaScript-Code in ein Funktionsobjekt, das dann aufgerufen werden kann. Es kann nicht auf lokale Variablen zugreifen, da der Code in einem separaten Bereich ausgeführt wird.Betrachten Sie diesen Code:
Bei
new Function('return (a = 22);')()
Verwendunga
würde die lokale Variable ihren Wert behalten. Einige JavaScript-Programmierer wie Douglas Crockford sind jedoch der Ansicht, dass keines von beiden verwendet werden sollte, es sei denn, dies ist unbedingt erforderlich , und das Auswerten / Verwenden desFunction
Konstruktors für nicht vertrauenswürdige Daten ist unsicher und unklug.quelle
new Function(code)
derselbe isteval('(function(){'+code+'})()')
oder ein völlig neuer Ausführungskontext?eval('(function(){'+code+'})')
, was ein Funktionsobjekt zurückgeben würde. Laut MDN erstellen "mit dem Funktionskonstruktor erstellte Funktionen keine Abschlüsse für ihre Erstellungskontexte; sie werden immer im Fensterkontext ausgeführt (es sei denn, der Funktionskörper beginnt mit einer Anweisung" use strict "; in diesem Fall ist der Kontext undefiniert). . "Nein.
In Ihrem Update rufen die Aufrufe dasselbe Ergebnis auf
evaluate
undfunc
führen zu demselben Ergebnis. Aber sie tun definitiv nicht "das Gleiche hinter den Kulissen". Diefunc
Funktion erstellt eine neue Funktion, führt sie jedoch sofort aus, während dieevaluate
Funktion den Code einfach vor Ort ausführt.Aus der ursprünglichen Frage:
Dies führt zu sehr unterschiedlichen Ergebnissen:
quelle
return eval('(' + string + ')');
damals, würden sie die gleichen Ergebnisse liefern.new Function
erstellt eine Funktion, die wiederverwendet werden kann.eval
führt nur die angegebene Zeichenfolge aus und gibt das Ergebnis der letzten Anweisung zurück. Ihre Frage ist falsch, als Sie versucht haben, eine Wrapper-Funktion zu erstellen, die Function verwendet, um eine Bewertung zu emulieren.Stimmt es, dass sie Code hinter den Vorhängen teilen? Ja, sehr wahrscheinlich. Genau der gleiche Code? Nein, sicher.
Zum Spaß ist hier meine eigene unvollständige Implementierung, bei der eval zum Erstellen einer Funktion verwendet wird. Hoffe, es bringt etwas Licht in den Unterschied!
Der größte Unterschied zwischen dieser und der neuen Funktion besteht darin, dass die Funktion nicht lexikalisch festgelegt ist. Es hätte also keinen Zugriff auf Schließungsvariablen und meine würde.
quelle
arguments.slice()
anstelle der for-Schleife verwenden? Oder wenn Argumente kein echtes Array sind ,[].slice.call(arguments, 1)
.Ich möchte nur auf die in den Beispielen verwendete Syntax und deren Bedeutung hinweisen:
Beachten Sie, dass die Funktion (...) () am Ende das "()" hat. Diese Syntax bewirkt, dass func die neue Funktion ausführt und die Zeichenfolge zurückgibt, keine Funktion, die eine Zeichenfolge zurückgibt. Wenn Sie jedoch Folgendes verwenden:
Jetzt gibt func eine Funktion zurück, die einen String zurückgibt.
quelle
Wenn Sie meinen, wird es die gleichen Ergebnisse liefern, dann ja ... aber nur zu bewerten (auch bekannt als "Bewertung dieser JavaScript-Zeichenfolge") wäre viel einfacher.
BEARBEITEN Unten:
Es ist wie zu sagen ... sind diese beiden mathematischen Probleme gleich:
1 + 1
1 + 1 + 1 - 1 + 1 - 1 * 1/1
quelle
Function
Objekt speichert die Zeichenfolge wahrscheinlich in einer privaten Mitgliedsvariablen, biseval
Sie die Funktion aufrufen.In diesem Beispiel sind die Ergebnisse dieselben, ja. Beide führen den übergebenen Ausdruck aus. Das macht sie so gefährlich.
Aber sie machen verschiedene Dinge hinter der Kulisse. Derjenige
new Function()
, der hinter den Kulissen involviert ist, erstellt aus dem von Ihnen angegebenen Code eine anonyme Funktion, die ausgeführt wird, wenn die Funktion aufgerufen wird.Das JavaScript, das Sie übergeben, wird technisch erst ausgeführt, wenn Sie die anonyme Funktion aufrufen. Dies steht im Gegensatz dazu,
eval()
dass der Code sofort ausgeführt wird und keine darauf basierende Funktion generiert wird.quelle
Does the Function() one use another stack call level than eval?
: Ich würde es annehmen, weileval()
es keine Funktion aus Ihrer Eingabe erstellt - es führt sie nur aus.new Function()
erstellt eine neue Funktion, die dann aufgerufen wird.