Als ich die JScript-Engine implementiert habe, habe ich mich dafür ausgesprochen , EVAL IS EVIL- Shirts bedrucken zu lassen, aber leider sind wir nie dazu gekommen.
Mein größtes Problem mit eval ist nicht der offensichtliche Angriff durch böswillige Code-Injektion, obwohl dies mit Sicherheit enorme Bedenken hervorruft. Mein größtes Problem dabei ist, dass die Leute es als einen wirklich großen Hammer benutzen, um wirklich kleine Probleme zu lösen. Die meisten realen Verwendungen, die ich im JScript-Team von "eval" in the wild gesehen habe, konnten mithilfe einer Nachschlagetabelle trivial gelöst werden. und da jedes Objekt in JScript bereits eine Nachschlagetabelle ist , war dies keine lästige Belastung. Eval startet den Compiler erneut und zerstört vollständig die Fähigkeit des Compilers, Ihren Code zu optimieren .
Weitere Gedanken in diesem Sinne finden Sie in meinen Artikeln aus dem Jahr 2003 zum Thema:
Allgemeine Übelkeit:
http://blogs.msdn.com/b/ericlippert/archive/2003/11/01/53329.aspx
Injection Attack Böse:
http://blogs.msdn.com/b/ericlippert/archive/2003/11/04/53335.aspx
eval
große Codestücke so zu erstellen, wie es Anwendungen wie JSPacker tun? JSPacker + gzip führt normalerweise zu kleineren Dateigrößen als jede der beiden Lösungen für sich. Wie Sie jedoch zu Recht betonen, wird ein Compiler im Wesentlichen zweimal mit demselben Code gestartet.eval()
ist nicht ein Sicherheitsrisiko auf den Client (Browser) Code.Bei den meisten Sicherheitslücken handelt es sich um die gleiche Art von Lücken wie bei der SQL-Injektion, nämlich um die Verkettung von Benutzereingaben in JavaScript-Code. Der Unterschied besteht darin, dass es zwar Möglichkeiten gibt, um sicherzustellen, dass dies mit SQL nicht geschieht, mit JavaScript jedoch nicht viel zu tun ist.
Als triviales und nutzloses Beispiel ein simpler JavaScript-Rechner:
Ein korrektes Anwendungsbeispiel sind einige der JavaScript-Packer, die JavaScript komprimieren, indem sie gebräuchliche Wörter herausnehmen und durch kurze Ersetzungen von 1 bis 2 Zeichen ersetzen. Der Packer gibt dann all dies zusammen mit dem String-Ersetzungscode aus, der auf dem generierten Wörterbuch basiert, und wertet dann das Ergebnis aus.
quelle
Es gibt einige Dinge , die in JS zu tun , ohne eine eval-ähnlichen Funktion (unmöglich sind
eval
,Function
und vielleicht auch mehr).Nimm
apply
zum Beispiel. Es ist einfach zu bedienen, wenn es für gewöhnliche Funktionsaufrufe verwendet wird:foo.apply(null, [a, b, c])
Aber wie würden Sie dies für Objekte tun, die Sie mithilfe einer neuen Syntax erstellen?
new Foo.apply(null, [a, b, c])
funktioniert nicht und macht auch keine ähnlichen Formen.Sie können diese Einschränkung jedoch mit
eval
oder umgehenFunction
(ich verwendeFunction
in diesem Beispiel):Beispiel:
Foo.New.apply(null, [a, b, c])
;Natürlich können Sie die Funktionen, die
Function.prototype.New
verwendet werden, manuell erstellen , aber dies ist nicht nur ausführlich und klobig, es muss (per Definition) endlich sein.Function
ermöglicht es dem Code, für eine beliebige Anzahl von Argumenten zu arbeiten.quelle
eval()
? "Eine etwas direkte Antwort meinerseits war die Entwicklung eines entwicklerorientierten API-Testbereichs. Wir gaben einen Textbereich auf einer Seite und eine Schaltfläche Ausführen. Der zentrale Punkt der Seite war, dass sie in der Lage waren, Dinge in Javascript mit unserer iframe-kommunizierenden API auszuprobieren, die in einer lokalen Umgebung nicht so einfach waren.
Alles, was in diesem Fall böswillig wäre, hätte auch der Entwickler tun können, der seine F12-Tools geöffnet hat.
quelle
Ich bin damit einverstanden, dass es sehr selten verwendet werden sollte, aber ich habe einen leistungsstarken Anwendungsfall für gefunden
eval
.In Firefox gibt es eine experimentelle neue Funktion namens asm.js, mit der ich gearbeitet habe. Dadurch kann eine begrenzte Teilmenge der Javascript-Sprache in nativen Code kompiliert werden. Ja, das ist großartig, aber es gibt Einschränkungen. Sie können sich die begrenzte Teilmenge von Javascript als eine C-ähnliche Sprache vorstellen, die in Javascript eingebettet ist. Es ist nicht wirklich dazu gedacht, von Menschen gelesen oder geschrieben zu werden.
Diese eingeschränkte Untermenge von Javascript ermöglicht es mir nicht, meinen zur Laufzeit generierten Code in den kompilierten Code einzufügen, sobald dieser kompiliert wurde.
Ich habe einen Code geschrieben, mit dem ein Benutzer in vertrauter Schreibweise einen mathematischen Ausdruck schreiben und ihn sofort in asm.js-Code konvertieren kann. Sofern ich den Code nicht auf dem Server verarbeiten lassen möchte (was ich nicht möchte),
eval
ist dies das einzige Tool, mit dem ich den resultierenden Code vom Browser in Echtzeit verarbeiten lassen kann.quelle
Wie von anderen hervorgehoben, ist das Wichtigste bei der Arbeit
eval
, es sicher zu halten. Zu diesem Zweck möchten Sie eine gründliche Argumentprüfung durchführen und deneval
Code einfach halten , da es im Allgemeinen sehr viel schwieriger ist, zur Laufzeit generierten Code zu verwalten und zu sichern.Davon abgesehen genieße ich es,
eval
für zwei Arten von Dingen zu verwenden (auch wenn es wahrscheinlich bessere, weniger böse Alternativen gibt):eval
es sich um eine Methode zum "expliziten Zwischenspeichern von Code" handelt, kann sie zur Verbesserung der Leistung verwendet werden. Beachten Sie, dass Optimierer ständig verbessert werden, es jedoch keine Garantie dafür gibt, was sie für Sie tun können. Indem Sie Dinge im Code explizit machen, können Sie dem Optimierer tatsächlich dabei helfen, intelligentere Entscheidungen zu treffen.Dieser Ansatz für vorkompilierte Objektiteratoren zeigt beispielsweise deutliche Leistungsvorteile bei der Verwendung
eval
für die Iteration von Objekteigenschaften. Es zeigt auch die Anfänge eines leistungsstarken Typsystems, das eine implizite Einschränkungsprüfung und vieles mehr zu geringen oder keinen Kosten bereitstellen kann.Viele erfahrene Javascript-Entwickler würden wahrscheinlich darauf hinweisen, dass dies ein Kaninchenbau ist, denn wenn Sie anfangen, Javascript auf diese Weise zu schreiben, ändern Sie im Wesentlichen die Art und Weise, wie Sie die Sprache verwenden. Dies ist jedoch möglicherweise nicht unbedingt eine schlechte Sache für diejenigen, die Javascript mögen, aber es fehlen auch grundlegende Sprachfunktionen, die nur durch eine Änderung der Art und Weise, wie wir die Sprache selbst verwenden, erreicht werden können.
quelle
Ich habe eine Situation, in der eval wie der Weg aussieht, eine Zeichenfolge auszuwerten und eine vorhandene Variable zurückzugeben, deren Name mit der Zeichenfolge identisch ist.
Ich habe mehrere Tabellen: table1ResultsTable, table2ResultsTable, tableNResultsTable. Ich habe Variablen mit den gleichen Namen eingerichtet, die jQuery-datierbare Objekte sind. Ich benutze diese, um die Tabellen einzurichten und mit jQuery datierbare Funktionen aufzurufen.
Jeder Tabelle ist class = "resultsTable" zugewiesen. Jetzt muss ich die Variable abrufen, wenn auf die Tabelle geklickt wird. Ich mache das:
Ich erhalte also die ID der Tabelle, in der die Zelle angeklickt wurde, die denselben Namen hat wie die zugehörige datierbare Objektvariable. Wenn jemand einen Verbesserungsvorschlag hat, würde ich gerne davon erfahren.
quelle
event.target.parentElement.parentElement.parentElement
ist schrecklich. Außerdem würde ich erwarten, dass der Aufruf von eval den Fehler "Referenzfehler: [ID] ist nicht definiert" generiert, es sei denn, Sie verwenden absichtlich auswertbare IDs (die fehlerhaft und falsch sind und möglicherweise zu seltsamen Ereignissen führen, wenn Sie aufhören doppelte IDs erzeugen).document.getElementById(ID).MySpecialProperty = MYSPECIALPROPERTYVALUE
(um nicht zu sagen, dass das auch großartig ist, aber es ist besser als eval). Eric Lippert betont: "Jedes Objekt in JScript ist bereits eine Nachschlagetabelle."