Question très intéressante! Nous allons creuser dans.
La cause racine
La racine de la différence est dans la façon dont Node.js évalue ces déclarations contre la façon dont le Chrome des outils de développement ne.
Ce Node.js n'
Node.js utilise le repl module pour cela.
À partir de la Node.js REPL code source:
self.eval('(' + evalCmd + ')',
self.context,
'repl',
function(e, ret) {
if (e && !isSyntaxError(e))
return finish(e);
if (typeof ret === 'function' &&
/^[\r\n\s]*function/.test(evalCmd) ||
e) {
// Now as statement without parens.
self.eval(evalCmd, self.context, 'repl', finish);
}
else {
finish(null, ret);
}
});
Cela agit comme exécutant ({}+{})
dans les outils de développement Chrome, qui produit également de l' "[object Object][object Object]"
comme vous le souhaitez.
Ce que les outils de développement chrome ne
Sur l'autre main Chrome dveloper les outils suivants:
try {
if (injectCommandLineAPI && inspectedWindow.console) {
inspectedWindow.console._commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null);
expression = "with ((window && window.console && window.console._commandLineAPI) || {}) {\n" + expression + "\n}";
}
var result = evalFunction.call(object, expression);
if (objectGroup === "console")
this._lastResult = result;
return result;
}
finally {
if (injectCommandLineAPI && inspectedWindow.console)
delete inspectedWindow.console._commandLineAPI;
}
Donc, fondamentalement, il effectue un call
sur l'objet avec l'expression. L'expression:
with ((window && window.console && window.console._commandLineAPI) || {}) {
{}+{};// <-- This is your code
}
Donc, comme vous pouvez le voir, l'expression est effectuée directement, sans l'habillage de la parenthèse.
Pourquoi Node.js actes différemment
Node.js source justifie ce:
// This catches '{a : 1}' properly.
Le nœud n'a pas toujours agir de la sorte. Ici est le réel s'engager à ce que l'a changé. Ryan laissé le commentaire suivant sur le changement: "Améliorer la façon dont REPL commandes sont evaled" avec un exemple de la différence.
Rhino
Mise à jour - OP a été intéressé par la façon dont Rhino se comporte (et pourquoi il se comporte comme le Chrome devtools et contrairement à nodejs).
Rhino utilise un complètement différent JS moteur contrairement aux outils de développement Chrome et Node.js's REPL qui utilisent l'V8.
Ici est la base de la ligne de la pipe de ce qui se passe quand vous eval une commande JavaScript avec Rhino dans le Rhino shell.
Le shell exécute org.mozilla.javascript.tools.shell.main
.
À son tour, il appelle cette new IProxy(IProxy.EVAL_INLINE_SCRIPT);
par exemple, si le code a été transmis directement à la ligne de l'interrupteur -e.
Cette frappe IProxy de l' run
méthode.
Il invoque evalInlineScript
(src). Il suffit de compile de la chaîne et est évaluée comme elle.
En gros:
Script script = cx.compileString(scriptText, "<command>", 1, null);
if (script != null) {
script.exec(cx, getShellScope()); // <- just an eval
}
Des trois, Rhino shell est celui qui fait la chose la plus proche d'un réel eval
sans emballage. Rhino est le plus proche d'un réel eval()
déclaration et vous pouvez vous attendre qu'il se comporte exactement comme eval
serait.