While [] + []
jest pustym łańcuchem, [] + {}
jest "[object Object]"
i {} + []
jest 0
. Dlaczego jest {} + {}
NaN?
> {} + {}
NaN
Moje pytanie jest dlaczego nie ({} + {}).toString()
jest "[object Object][object Object]"
natomiast NaN.toString()
to "NaN"
, ta część ma odpowiedź już tutaj .
Moje pytanie brzmi: dlaczego dzieje się to tylko po stronie klienta? Po stronie serwera ( Node.js ) {} + {}
jest "[object Object][object Object]"
.
> {} + {}
'[object Object][object Object]'
Podsumowując :
Po stronie klienta:
[] + [] // 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]"
W 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
źródło
źródło
{}
zależności od kontekstu można to zinterpretować jako wyrażenie lub jako obiekt pierwotny. Może kod jest taki sam na kliencie i na serwerze, ale interpretuje go{}
inaczej ze względu na inny kontekst wprowadzania kodu.Odpowiedzi:
Zaktualizowana uwaga: zostało to naprawione w Chrome 49 .
Bardzo ciekawe pytanie! Zagłębmy się.
Podstawowa przyczyna
Źródłem różnicy jest sposób, w jaki Node.js ocenia te stwierdzenia, w porównaniu z narzędziami programistycznymi Chrome.
Co robi Node.js
Node.js używa do tego modułu repl .
Z kodu źródłowego REPL Node.js :
Działa to tak samo, jak działanie
({}+{})
w narzędziach programistycznych Chrome, które również działają"[object Object][object Object]"
zgodnie z oczekiwaniami.Co robią narzędzia programistyczne Chrome
Z drugiej strony narzędzia Chrome dveloper wykonują następujące czynności :
Więc zasadniczo wykonuje a
call
na obiekcie z wyrażeniem. Wyrażenie to:Zatem, jak widać, wyrażenie jest ewaluowane bezpośrednio, bez nawiasów zawijających.
Dlaczego Node.js działa inaczej
Źródło Node.js uzasadnia to:
Węzeł nie zawsze zachowywał się w ten sposób. Oto faktyczne zatwierdzenie, które go zmieniło . Ryan zostawił następujący komentarz dotyczący zmiany: „Popraw sposób oceny poleceń REPL” z przykładem różnicy.
Nosorożec
Aktualizacja - OP był zainteresowany tym, jak zachowuje się Rhino (i dlaczego zachowuje się jak Devtools Chrome iw przeciwieństwie do nodejs).
Rhino używa zupełnie innego silnika JS w przeciwieństwie do narzędzi programistycznych Chrome i REPL Node.js, które używają V8.
Oto podstawowa rura pokazująca, co się dzieje, gdy oceniasz polecenie JavaScript za pomocą Rhino w powłoce Rhino.
Pocisk działa
org.mozilla.javascript.tools.shell.main
.Z kolei wywołuje to
new IProxy(IProxy.EVAL_INLINE_SCRIPT);
na przykład, jeśli kod został przekazany bezpośrednio za pomocą przełącznika wbudowanego -e.To trafia w
run
metodę IProxy .Wywołuje
evalInlineScript
( src ). To po prostu kompiluje ciąg i ocenia go.Gruntownie:
Spośród tych trzech, powłoka Rhino jest tą, która jest najbliższa rzeczywistej
eval
bez żadnego opakowania. Rhino's jest najbliżej rzeczywistegoeval()
stwierdzenia i możesz oczekiwać, że zachowa się dokładnie tak, jakeval
by.źródło
eval
)evaluateOn
. W węźle wszystko jest bardzo dobrze udokumentowane - mają dedykowany moduł REPL z całą historią ładnie i przytulnie na git, po wcześniejszym używaniu REPL w moich własnych programach, wiedziałem, gdzie szukać :) Cieszę się, że Ci się podobało i znalazłem to pomocne, ale zawdzięczam to raczej znajomości tych podstaw kodu (dev-tools i nodejs) niż mojemu intelektowi. Często najłatwiej jest dotrzeć prosto do źródła.