web-dev-qa-db-fra.com

Pourquoi {} + {} n'est plus dans NaN dans la console Chrome?)?

J'ai remarqué aujourd'hui que Chrome 49 ne renvoie plus NaN lorsque vous tapez {}+{} dans la console. Au lieu de cela, il affiche la chaîne [object Object][object Object].

Pourquoi est-ce? La langue a-t-elle changé?

143
Filip Haglund

Chrome devtools encapsule maintenant automatiquement tout ce qui commence par { et se termine par } dans une paire implicite de parenthèses ( voir le code ), pour forcer son évaluation en tant qu'expression. De cette façon, {} crée un objet vide maintenant. Vous pouvez le voir si vous remontez dans l’histoire (), la ligne précédente sera contenue dans (…).

Pourquoi? Je ne sais pas, mais Je suppose que cela réduit la confusion pour les débutants qui ne connaissent pas le problème littéral bloc-objet-objet. Il est également plus utile si vous souhaitez simplement évaluer une expression.

Et en fait c'est le raisonnement, comme expliqué dans bug 499864 . Pure commodité. Et parce que node ​​REPL l'avait) aussi ( voir le code ).

149
Bergi

Si vous cliquez sur la flèche du haut après avoir coché cette case, vous remarquerez que, au lieu de {} + {} il affiche ({} + {}), ce qui entraîne "[object Object][object Object]".

En comparaison, dans Firefox, {} + {} affiche toujours NaN, mais si vous faites ({} + {}) _ il affiche également "[object Object][object Object]".

On dirait donc que Chrome ajoute automatiquement les parenthèses qui l'entourent lorsqu'il voit cette opération.

44
J. Titus

À partir de Chrome 54 en ce qui concerne la console:

????-"I converted that block to an Object for you" -Clippy Malheureusement, j'ai ajouté la citation Clippy moi-même. La console ne donne aucune information sur ce qu’elle a fait pour vous.

Les nouvelles règles sont incroyablement simples , ce qui nous évite d'avoir à taper péniblement ces 2 caractères difficiles o= Ou 0, Avant de les coller. Les objets littéraux dans la console:

  • Si vous avez un code qui commence par: espace blanc facultatif, (aucun commentaire n'est autorisé) suivi d'un {;
  • et ce code pourrait être interprété comme un objet;
  • et cet objet n'est suivi d'aucun autre code, à moins que:
  • le code après le premier objet est un opérateur binaire,
  • alors il peut y avoir autant d'opérations que vous le souhaitez, y compris des groupements
  • à condition que l'opérateur final ait un littéral Object dans la position de main droite;
  • et cet objet final n'a pas été groupé par parens
  • et ce code ne se termine pas par un point-virgule
  • et aucun commentaire ne suit le code (les commentaires internes sont autorisés tant qu'ils ne sont pas dans la position initiale ou finale)
  • alors et seulement alors, votre JavaScript (qui peut être ou ne pas être du code valide) sera réinterprété comme un objet valide. Vous ne serez pas informé que votre code a été réinterprété.

{wat:1}),({wat:2} est finalement à nouveau une erreur.

{let i=0;var increment=_=>i++} Est correctement autorisé, enfin, ce qui est une bonne façon de faire des fermetures.

Cependant, ce qui suit est incorrectement un objet, c’est aussi pratique que mentionné par @Bergi, JS interprète à tort pour vous aider! La spécification indique qu'il s'agit d'un bloc avec une instruction étiquetée "foo" avec un littéral 1 qui n'est attribué à rien.

{foo:1}

Ce qui précède devrait être le même que

if(1) {
    foo: 1
}

Ce qui suit est traité correctement comme un bloc ... car il a un commentaire devant lui!

//magic comment
{foo:1}

Alors est-ce:

{foo:1}
//also magic

C'est un objet:

{foo:
//not so magic comment
1}

C'est une erreur

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

Alors est-ce:

{foo:1}.foo

C'est bon:

1..wat

undefined

alors est-ce:

['foo'][0]

Le prochain est correctement interprété comme un objet inséré dans la position de l'expression avec un 0,, Ce qui correspond généralement à la manière dont nous assurons sans équivoque que nous avons une expression plutôt qu'une déclaration.

0,{foo:1}.foo

Je ne comprends pas pourquoi ils emballent la valeur en parens. JS a des décisions de conception ridicules, mais essayer de le rendre plus agréable dans cette situation particulière n’est pas vraiment une option, la console doit exécuter JS correctement, et nous devons être sûrs que chrome il ne faut pas seulement deviner qu'il pense que nous voulions vraiment faire autre chose.

Si vous n'aimez pas les opérateurs de virgule, vous pouvez utiliser l'affectation

x = {foo:1}.foo

Car tel quel

{} + {} + {}

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

;{} + {} + {}

"NaN[object Object]"

Fou et cohérent je peux traiter avec ... fou et incohérent non merci!

4
James Wakefield