Mientras que [] + []
es una cadena vacía, [] + {}
es "[object Object]"
y {} + []
es 0
. ¿Por qué es {} + {}
NaN?
> {} + {}
NaN
Mi pregunta no es por qué ({} + {}).toString()
es "[object Object][object Object]"
mientras que NaN.toString()
es "NaN"
, esta parte tiene una respuesta aquí ya .
Mi pregunta es ¿por qué sucede esto solo en el lado del cliente? En el lado del servidor ( Node.js ) {} + {}
está "[object Object][object Object]"
.
> {} + {}
'[object Object][object Object]'
Resumiendo :
En el lado del cliente:
[] + [] // 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]"
En 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
fuente
fuente
{}
puede interpretarse como una expresión o como un objeto primitivo según el contexto. Tal vez el código sea el mismo en el cliente y en el servidor, pero se interpreta de manera{}
diferente debido al contexto diferente de ingresar el código.Respuestas:
Nota actualizada: esto se ha solucionado en Chrome 49 .
Muy interesante pregunta! Vamos a profundizar en.
La causa principal
La raíz de la diferencia está en cómo Node.js evalúa estas declaraciones frente a cómo lo hacen las herramientas de desarrollo de Chrome.
Lo que hace Node.js
Node.js usa el módulo repl para esto.
Del código fuente Node.js REPL :
Esto actúa como si se ejecutara
({}+{})
en las herramientas de desarrollador de Chrome, que también produce"[object Object][object Object]"
lo que cabría esperar.Lo que hacen las herramientas para desarrolladores de Chrome
Por otro lado, las herramientas de Chrome Dveloper hacen lo siguiente :
Entonces, básicamente, realiza un
call
en el objeto con la expresión. La expresión es:Entonces, como puede ver, la expresión se está evaluando directamente, sin el paréntesis de ajuste.
Por qué Node.js actúa de manera diferente
La fuente de Node.js justifica esto:
Nodo no siempre actuaba así. Aquí está la confirmación real que lo cambió . Ryan dejó el siguiente comentario sobre el cambio: "Mejore cómo se evaden los comandos REPL" con un ejemplo de la diferencia.
Rinoceronte
Actualización: OP estaba interesado en cómo se comporta Rhino (y por qué se comporta como las herramientas de Chrome y a diferencia de nodejs).
Rhino utiliza un motor JS completamente diferente a diferencia de las herramientas de desarrollador de Chrome y REPL de Node.js, que usan V8.
Aquí está la línea básica de lo que sucede cuando evalúa un comando de JavaScript con Rhino en el shell de Rhino.
La cáscara corre
org.mozilla.javascript.tools.shell.main
.A su vez, llama a esto,
new IProxy(IProxy.EVAL_INLINE_SCRIPT);
por ejemplo, si el código se pasó directamente con el modificador en línea -e.Esto golpea el
run
método de IProxy .Invoca
evalInlineScript
( src ). Esto simplemente compila la cadena y la evalúa.Básicamente:
De los tres, el caparazón de Rhino es el que hace lo más parecido a un real
eval
sin ningún tipo de envoltura. Rhino's es el más cercano a unaeval()
declaración real y puede esperar que se comporte exactamente como loeval
haría.fuente
eval
)evaluateOn
. En el nodo, todo está muy bien documentado: tienen un módulo REPL dedicado con toda la historia agradable y acogedor en git, habiendo usado REPL antes en mis propios programas, sabía dónde buscar :) Me alegra que te haya gustado y hayas encontrado es útil, pero se lo debo a mi familiaridad con estas bases de código (dev-tools y nodejs) en lugar de mi intelecto. Ir directamente a la fuente suele ser siempre lo más fácil.