¿Por qué {} + {} ya no es NaN en Chrome console?


He notado hoy que Chrome 49 ya no sale NaN cuando se escribe {}+{} en la consola. En su lugar, muestra la cadena [object Object][object Object].

¿Por qué es esto? ¿Cambió el idioma?

Author: Filip Haglund, 2016-04-06

3 answers

Chrome devtools ahora envuelve automáticamente todo lo que comienza con { y termina con }en un par de paréntesis implícito ( ver código ), para forzar su evaluación como una expresión. De esa manera, {} crea un objeto vacío ahora. Usted puede ver esto si usted va detrás a través de la historia (), la línea anterior figurará en (…).

¿Por qué? No lo sé, pero Podría suponer que reduce la confusión para los novatos que no saben del bloque-vs-objeto-literal y también es más útil si solo quieres evaluar una expresión.

Y de hecho ese es el razonamiento, como se discutió en bug 499864. Pura conveniencia. Y porque nodo REPL lo tenía también ( ver código ).

 148
Author: Bergi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:33:19

Si presiona la flecha hacia arriba después de verificar esto, notará que en lugar de {} + {} se muestra ({} + {}), lo que resulta en "[object Object][object Object]".

En comparación, en Firefox, {} + {} todavía muestra NaN, pero si lo haces ({} + {}) también muestra "[object Object][object Object]".

Por lo tanto, parece que Chrome está agregando el paréntesis circundante automáticamente cuando ve esta operación.

 43
Author: J. Titus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-05 22:23:23

A partir de Chrome 54 con respecto a la consola:

- "Convertí ese bloque en un Objeto para ti" - Clippy Desafortunadamente, yo mismo agregué la cita Clippy. La consola no proporciona información sobre lo que ha hecho por usted.

Las nuevas reglas son increíblemente simples ahorrándonos la molestia de escribir laboriosamente estos 2 gráficos difíciles o= o 0, antes de pegar Literales de objetos en la consola:

  • Si tiene código que comienza con: espacios en blanco opcionales, (sin comentarios permitido) seguido de un {;
  • y ese código podría interpretarse como un objeto;{[37]]}
  • y ese objeto no es seguido por ningún otro código, a menos que:
  • el código después del primer objeto es un operador binario,
  • entonces puede haber tantas operaciones como desee incluyendo agrupaciones
  • siempre que el operador final tenga un objeto literal en la posición de la mano derecha;
  • y ese Objeto final no se ha agrupado en paréntesis
  • y ese código no es terminado con punto y coma
  • y no hay comentarios después del código (los comentarios internos están permitidos siempre que no estén en la posición inicial o final)
  • entonces y solo entonces su JavaScript (que puede o no ser realmente código válido) será reinterpretado como un objeto válido. No se le informará de que su código ha sido reinterpretado.

{wat:1}),({wat:2} Es finalmente un error de nuevo.

{let i=0;var increment=_=>i++} se permite correctamente, finalmente, que es bastante buena manera de hacer cierres.

Sin embargo, lo siguiente es incorrectamente un objeto, esto es tan conveniente como lo menciona @Bergi, interpreta JS mal para ayudarte! La especificación dice que es un bloque con una declaración etiquetada " foo " con un literal 1 que no está asignado a nada.

{foo:1}

Lo anterior debe ser lo mismo que

if(1) {
    foo: 1
}

Lo siguiente se trata correctamente como un bloque... ¡porque tiene un comentario delante!

//magic comment
{foo:1}

Así es esto:

{foo:1}
//also magic

Este es un Objeto:

{foo:
//not so magic comment
1}

Esto es un error

//not so magic comment
{foo:1}.foo

Así es esto:

{foo:1}.foo

Esto está bien:

1..wat

undefined

Así es esto:

['foo'][0]

El siguiente se interpreta correctamente como un objeto golpeado en la posición de expresión con un 0, que es generalmente cómo nos aseguramos inequívocamente de que tenemos una expresión en lugar de una declaración.

0,{foo:1}.foo

No entiendo por qué envuelven el valor en paréntesis. JS tiene algunos ridículas decisiones de diseño, pero tratando de hacer que se comporte mejor en esta situación no es realmente una opción, la consola tiene que ejecutar JS correctamente, y tenemos que estar seguros de que Chrome no es solo adivinar que piensa que realmente significaba que hacer algo más.

Si no te gustan los operadores de coma, puedes usar asignación

x = {foo:1}.foo

Porque tal como está

{} + {} + {}

"[object Object][object Object][object Object]"

;{} + {} + {}

"NaN[object Object]"

Loco y consistente con el que puedo lidiar... loco y inconsistente no gracias!

 4
Author: James Wakefield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-21 05:31:41