js modules from JavaScript running in the browser has many advantages because it allows you to use Node. js modules for client-side JavaScript applications without having to use a server with Node. js just to implement functionality that is already available as a Node. js module that is available via an npm package.
It allows developers to use a single language (JavaScript) on both the server-side and the Client-Side. This inevitably improves how efficiently and fast applications can run while decreasing their development time and maintenance costs.
Node. js is a server-side, packaged software that contains predefined processes to accomplish specific tasks. As a server-side runtime, every Node. js process is executed on a server; essentially working on the backend aspect of an application to manage data.
Node. js is a JavaScript framework for writing server-side applications. In its simplest form it allows you to trigger small JavaScript programs from the command line without any browser involved. For example, assuming node is installed if you write a JavaScript program in a file called hello.
Updated note: this has been fixed in Chrome 49.
Very interesting question! Let's dig in.
The root of the difference is in how Node.js evaluates these statements vs. how the Chrome development tools do.
Node.js uses the repl module for this.
From the Node.js REPL source code:
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);
}
}
);
This acts just like running ({}+{})
in the Chrome developer tools, which also produces "[object Object][object Object]"
as you'd expect.
On the other hand Chrome dveloper tools does the following:
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;
}
So basically, it performs a call
on the object with the expression. The expression being:
with ((window && window.console && window.console._commandLineAPI) || {}) {
{}+{};// <-- This is your code
}
So, as you can see, the expression is being evaluted directly, without the wrapping parenthesis.
Node.js's source justifies this:
// This catches '{a : 1}' properly.
Node did not always act like this. Here is the actual commit that changed it. Ryan left the following comment on the change: "Improve how REPL commands are evaled" with an example of the difference.
Update - OP was interested in how Rhino behaves (and why it behaves like the Chrome devtools and unlike nodejs).
Rhino uses a completely different JS engine unlike the Chrome developer tools and Node.js's REPL which both use V8.
Here is the basic pipe line of what happens when you eval a JavaScript command with Rhino in the Rhino shell.
The shell runs org.mozilla.javascript.tools.shell.main
.
In turn, it calls this new IProxy(IProxy.EVAL_INLINE_SCRIPT);
for example, if the code was passed directly with the inline switch -e.
This hits IProxy's run
method.
It invokes evalInlineScript
(src). This simply compiles the string and evals it.
Basically:
Script script = cx.compileString(scriptText, "<command>", 1, null);
if (script != null) {
script.exec(cx, getShellScope()); // <- just an eval
}
Out of the three, Rhino's shell is the one that does the closest thing to an actual eval
without any wrapping. Rhino's is the closest to an actual eval()
statement and you can expect it to behave exactly like eval
would.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With