Güncellenmiş not: Bu, Chrome 49'da düzeltildi .
Çok ilginç bir soru! Hadi kazalım.
Temel neden
Farkın kökü, Node.js'nin bu açıklamaları nasıl değerlendirdiği ve Chrome geliştirme araçlarının nasıl işlediğidir.
Node.js ne yapar
Node.js bunun için repl modülünü kullanır .
Node.js REPL kaynak kodundan :
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);
}
}
);
Bu, tıpkı beklediğiniz gibi ({}+{})
üretilen Chrome geliştirici araçlarında çalışmak gibi davranır "[object Object][object Object]"
.
Chrome geliştirici araçlarının yaptıkları
Öte yandan Chrome dveloper araçları şunları yapar :
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;
}
Temel olarak, call
ifadeyle birlikte nesne üzerinde bir a gerçekleştirir . İfade şu şekildedir:
with ((window && window.console && window.console._commandLineAPI) || {}) {
{}+{};// <-- This is your code
}
Gördüğünüz gibi, ifade sarma parantezi olmadan doğrudan değerlendiriliyor.
Node.js neden farklı davranıyor
Node.js kaynağı bunu haklı çıkarır:
// This catches '{a : 1}' properly.
Düğüm her zaman böyle davranmadı. İşte onu değiştiren gerçek taahhüt . Ryan değişiklik hakkında şu yorumu yaptı: "REPL komutlarının değerlendirilme şeklini geliştirin" farkına bir örnekle.
Gergedan
Güncelleme - OP, Rhino'nun nasıl davrandığıyla (ve neden Chrome aygıtları gibi ve düğümlerin aksine) davrandığıyla ilgileniyordu.
Rhino, Chrome geliştirici araçlarından ve her ikisi de V8 kullanan Node.js'nin REPL'sinden farklı olarak tamamen farklı bir JS motoru kullanıyor.
İşte Rhino kabuğundaki Rhino ile bir JavaScript komutu değerlendirdiğinizde gerçekleşen temel boru hattı.
Temelde:
Script script = cx.compileString(scriptText, "<command>", 1, null);
if (script != null) {
script.exec(cx, getShellScope()); // <- just an eval
}
Üçünden Rhino'nun kabuğu, eval
herhangi bir sargı olmadan bir gerçeğe en yakın şeyi yapan kabuktur . Gergedan, gerçek bir eval()
ifadeye en yakın olanıdır ve tam olarak olduğu gibi davranmasını bekleyebilirsiniz eval
.