Während [] + []
ist eine leere Zeichenfolge, [] + {}
ist "[object Object]"
und {} + []
ist 0
. Warum ist {} + {}
NaN?
> {} + {}
NaN
Meine Frage ist nicht , warum ({} + {}).toString()
ist "[object Object][object Object]"
während NaN.toString()
ist "NaN"
, dieser Teil bereits eine Antwort hier hat .
Meine Frage ist, warum dies nur auf der Client-Seite geschieht. Auf der Serverseite ( Node.js ) {} + {}
ist "[object Object][object Object]"
.
> {} + {}
'[object Object][object Object]'
Zusammenfassend :
Auf der Client-Seite:
[] + [] // Returns ""
[] + {} // Returns "[object Object]"
{} + [] // Returns 0
{} + {} // Returns NaN
NaN.toString() // Returns "NaN"
({} + {}).toString() // Returns "[object Object][object Object]"
var a = {} + {}; // 'a' will be "[object Object][object Object]"
In Node.js:
[] + [] // Returns "" (like on the client)
[] + {} // Returns "[object Object]" (like on the client)
{} + [] // Returns "[object Object]" (not like on the client)
{} + {} // Returns "[object Object][object Object]" (not like on the client)
javascript
node.js
eval
google-chrome-devtools
web-developer-toolbar
Ionică Bizău
quelle
quelle
{}
dies je nach Kontext entweder als Ausdruck oder als Objektprimitiv interpretiert werden kann. Möglicherweise ist der Code auf dem Client und auf dem Server gleich, wird jedoch{}
aufgrund des unterschiedlichen Kontextes für die Eingabe des Codes unterschiedlich interpretiert .Antworten:
Aktualisierter Hinweis: Dies wurde in Chrome 49 behoben .
Sehr interessante Frage! Lass uns eintauchen.
Die Grundursache
Die Wurzel des Unterschieds liegt darin, wie Node.js diese Aussagen im Vergleich zu den Chrome-Entwicklungstools bewertet.
Was Node.js macht
Node.js verwendet hierfür das Repl- Modul.
Aus dem REPL-Quellcode von Node.js :
Dies funktioniert genauso wie das Ausführen
({}+{})
in den Chrome-Entwicklertools, die ebenfalls"[object Object][object Object]"
wie erwartet produzieren.Was die Chrome-Entwicklertools tun
Auf der anderen Seite führt Chrome Dveloper Tools Folgendes aus :
Im Grunde führt es ein
call
Objekt mit dem Ausdruck aus. Der Ausdruck ist:Wie Sie sehen können, wird der Ausdruck direkt ohne die umschließende Klammer ausgewertet.
Warum Node.js anders verhält
Die Quelle von Node.js rechtfertigt dies:
Node hat sich nicht immer so verhalten. Hier ist das tatsächliche Commit, das es geändert hat . Ryan hinterließ den folgenden Kommentar zu der Änderung: "Verbessern Sie die Auswertung von REPL-Befehlen" mit einem Beispiel für den Unterschied.
Nashorn
Update - OP war daran interessiert, wie sich Rhino verhält (und warum es sich wie die Chrome-Devtools und im Gegensatz zu NodeJS verhält).
Rhino verwendet eine völlig andere JS-Engine als die Chrome-Entwicklertools und die REPL von Node.js, die beide V8 verwenden.
Hier ist die grundlegende Pipeline, was passiert, wenn Sie einen JavaScript-Befehl mit Rhino in der Rhino-Shell auswerten.
Die Shell läuft
org.mozilla.javascript.tools.shell.main
.Im Gegenzug fordert er dies
new IProxy(IProxy.EVAL_INLINE_SCRIPT);
beispielsweise, wenn der Code direkt mit dem Inline - Schalter -en übergeben wurde.Dies trifft die IProxy-
run
Methode.Es ruft
evalInlineScript
( src ) auf. Dadurch wird der String einfach kompiliert und ausgewertet.Grundsätzlich:
Von den dreien ist Rhinos Muschel diejenige, die einer tatsächlichen Sache am nächsten kommt,
eval
ohne sie einzuwickeln. Rhino's kommt einer tatsächlicheneval()
Aussage am nächsten und Sie können erwarten, dass sie sich genau so verhält, wie sie es tuneval
würde.quelle
eval
)evaluateOn
. In Node ist alles sehr gut dokumentiert - sie haben ein dediziertes REPL-Modul mit der ganzen Geschichte, nett und gemütlich auf Git. Nachdem ich REPLs zuvor in meinen eigenen Programmen verwendet hatte, wusste ich, wo ich suchen musste :) Ich bin froh, dass es Ihnen gefallen hat und Sie es gefunden haben es ist hilfreich, aber ich verdanke es eher meiner Vertrautheit mit diesen Codebasen (dev-tools und nodejs) als meinem Intellekt. Es ist oft immer am einfachsten, direkt zur Quelle zu gehen.