J'ai remarqué aujourd'hui que Chrome 49 ne sort plus NaN
lorsque vous tapez {}+{}
dans la console. Au lieu de cela, il génère la chaîne [object Object][object Object]
.
Pourquoi est-ce? La langue a-t-elle changé?
J'ai remarqué aujourd'hui que Chrome 49 ne sort plus NaN
lorsque vous tapez {}+{}
dans la console. Au lieu de cela, il génère la chaîne [object Object][object Object]
.
Pourquoi est-ce? La langue a-t-elle changé?
Réponses:
Les outils de développement Chrome encapsulent désormais automatiquement tout ce qui commence par {
et se termine par }
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 revenez dans l'historique ( ↑), la ligne précédente sera contenue dans (…)
.
Pourquoi? Je ne sais pas, mais je pourrais supposer que cela réduit la confusion pour les débutants qui ne connaissent pas la chose bloc-vs-objet-littéral, et c'est aussi plus utile si vous voulez simplement évaluer une expression.
Et en fait, c'est le raisonnement, comme indiqué dans le bogue 499864 . Pratique pure. Et parce que le nœud REPL l'avait aussi ( voir code ).
{a:1}),({b:2}
devrait générer une erreur, pas produire un objet.
)
au cas où elle serait dans un commentaire, par exemple {a:3} // :-}
pourrait encore produire un objet.
Si vous appuyez sur la flèche vers le haut après avoir vérifié cela, vous remarquerez qu'au lieu de {} + {}
cela ({} + {})
, elle s'affiche , ce qui entraîne "[object Object][object Object]"
.
En comparaison, dans Firefox, {} + {}
s'affiche toujours NaN
, mais si vous le faites, ({} + {})
il s'affiche également "[object Object][object Object]"
.
Donc, il semble que Chrome ajoute automatiquement les parenthèses environnantes lorsqu'il voit cette opération.
{} + {}
lorsqu'il n'est pas "nettoyé" ({} + {})
est traité comme + {}
parce qu'il {}
est analysé comme un bloc vide.
{}
est juste un bloc de code vide et est ignoré, nous laissant avec +{}
, qui est un objet unaire +
et vide initialiseur. +
contraindra son argument en nombre, ce qui implique la conversion de l'objet en primitive (qui finira par être un toString
dans ce cas, ce qui entraînera "[object Object]"
), et ainsi nous obtenons +"[object Object]"
ce qui est NaN
parce "[object Object]"
qu'il ne peut pas être converti en un nombre valide.
Malheureusement, j'ai ajouté moi-même la citation de Clippy. 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 laborieusement ces 2 caractères difficiles o=
ou 0,
avant de coller des objets littéraux dans la console:
{
;{wat:1}),({wat:2}
Est enfin une erreur à nouveau.
{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 juste pour la commodité comme mentionné par @Bergi, il interprète mal JS pour vous aider! La spécification dit que c'est un bloc avec une instruction étiquetée "foo" avec un littéral 1 qui n'est assigné à rien.
{foo:1}
Ce qui précède doit ê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
Ceci 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
est donc ceci:
['foo'][0]
Le suivant est correctement interprété comme un objet enfoncé dans la position de l'expression avec un, 0,
ce qui est généralement la façon dont nous nous assurons sans ambiguïté d'avoir une expression au lieu d'une instruction.
0,{foo:1}.foo
Je ne comprends pas pourquoi ils enveloppent la valeur dans des parenthèses. JS a des décisions de conception ridicules, mais essayer de le rendre plus agréable dans cette situation n'est pas vraiment une option, la console doit exécuter JS correctement, et nous devons être sûrs que Chrome ne se contente pas de deviner qu'il pense que nous voulait vraiment faire autre chose.
Si vous n'aimez pas les opérateurs de virgule, vous pouvez utiliser l'affectation
x = {foo:1}.foo
Parce que tel quel
{} + {} + {}
"[object Object][object Object][object Object]"
;{} + {} + {}
"NaN[object Object]"
Fou et cohérent je peux gérer ... fou et incohérent non merci!
{foo:1}
et {foo:1}//
produire la même chose. Dans Chrome JS REPL, ils ne le font pas. Le REPL fait plus que simplement évaluer JS. Il traite les chaînes et décide de différentes choses.
var x = eval('{a:1}')
En JavaScript valide, x vaut maintenant 1, pas l'objet le plus intuitif {a: 1}. Oui, c'est bizarre, mais vous ne pouvez pas simplement changer la langue parce que cela fait des choses bizarres. Tout autre que les chaînes JSON sont interprétés comme JavaScript et évalués. Taper 0,
avant de coller le JSON n'est pas difficile, sinon je serais heureux avec un avertissement indiquant que la chaîne a été interprétée comme un objet au lieu de JavaScript pour plus de commodité.
var e = {}; e.toString()
et vous verrez ce que je veux dire