Hoje notei que o Chrome 49 não sai mais NaN
quando você digita {}+{}
no console. Em vez disso, gera a string [object Object][object Object]
.
Por que é isso? O idioma mudou?
Hoje notei que o Chrome 49 não sai mais NaN
quando você digita {}+{}
no console. Em vez disso, gera a string [object Object][object Object]
.
Por que é isso? O idioma mudou?
Respostas:
As ferramentas do Chrome agora envolvem automaticamente tudo o que começa {
e termina com }
um par implícito de parênteses ( consulte o código ), para forçar sua avaliação como uma expressão. Dessa forma, {}
cria um objeto vazio agora. Você pode ver isso se voltar ao histórico ( ↑), a linha anterior estará contida (…)
.
Por quê? Não sei, mas acho que isso reduz a confusão para iniciantes que não sabem o que é literalmente bloco versus objeto, e também é mais útil se você quiser apenas avaliar uma expressão.
E, de fato, esse é o raciocínio, conforme discutido no bug 499864 . Pura conveniência. E porque o nó REPL também o tinha ( consulte o código ).
{a:1}),({b:2}
deve gerar um erro, não produzir um objeto.
)
, caso esteja em um comentário, por exemplo, {a:3} // :-}
ainda pode produzir um objeto.
Se você acertar a seta para cima depois de verificar isso, você vai perceber que em vez de {} + {}
ele exibe ({} + {})
, o que resulta em "[object Object][object Object]"
.
Em comparação, no Firefox, {} + {}
ainda é exibido NaN
, mas se você o fizer ({} + {})
, também será exibido "[object Object][object Object]"
.
Portanto, parece que o Chrome está adicionando os parênteses circundantes automaticamente quando vê essa operação.
{} + {}
quando não "higienizado" ({} + {})
é tratado como + {}
porque {}
é analisado como um bloco vazio.
{}
é apenas um bloco de código vazio e é desconsiderada, deixando-nos com +{}
, que é um +
objeto unário e vazio inicializador. +
coagirá seu argumento ao número, o que envolve converter o objeto em um primitivo (que acabará sendo um toString
neste caso, resultando em "[object Object]"
) e, portanto, obtemos o +"[object Object]"
que é NaN
porque "[object Object]"
não pode ser convertido em um número válido.
Infelizmente, eu adicionei a citação Clippy. O console não fornece informações sobre o que fez por você.
As novas regras são incrivelmente simples, poupando o trabalho de digitar laboriosamente esses 2 charcters difíceis o=
ou 0,
antes de colar Literais de Objetos no console:
{
;{wat:1}),({wat:2}
É finalmente um erro novamente.
{let i=0;var increment=_=>i++}
é corretamente permitido, finalmente, o que é uma ótima maneira de fazer fechamentos.
No entanto, o objeto a seguir é incorretamente incorreto; isso é tão conveniente quanto mencionado por @Bergi; ele interpreta JS errado para ajudá-lo! A especificação diz que é um bloco com uma declaração rotulada "foo" com um literal 1 que não está atribuído a nada.
{foo:1}
O acima deve ser o mesmo que
if(1) {
foo: 1
}
O seguinte é tratado corretamente como um bloco ... porque ele tem um comentário à sua frente!
//magic comment
{foo:1}
Então é isso:
{foo:1}
//also magic
Este é um objeto:
{foo:
//not so magic comment
1}
Isto é um erro
//not so magic comment
{foo:1}.foo
Então é isso:
{foo:1}.foo
Isto é bom:
1..wat
undefined
então é isso:
['foo'][0]
O próximo é corretamente interpretado como um objeto atingido na posição de expressão com um 0,
que geralmente é como garantimos inequivocamente que temos uma expressão em vez de uma declaração.
0,{foo:1}.foo
Não entendo por que eles agrupam o valor em parênteses. O JS tem algumas decisões de design ridículas, mas tentar torná-lo melhor nessa situação não é realmente uma opção, o console precisa executar o JS corretamente e precisamos ter certeza de que o chrome não está apenas supondo que acha que realmente significava fazer outra coisa.
Se você não gosta de operadores de vírgula, pode usar a atribuição
x = {foo:1}.foo
Porque como está
{} + {} + {}
"[object Object][object Object][object Object]"
;{} + {} + {}
"NaN[object Object]"
Louco e consistente eu posso lidar com ... louco e inconsistente não, obrigado!
{foo:1}
e {foo:1}//
produzir a mesma coisa. No Chrome JS REPL, eles não. O REPL está fazendo mais do que apenas avaliar o JS. Ele está processando as strings e decidindo fazer coisas diferentes.
var x = eval('{a:1}')
No JavaScript válido, x é agora 1, não o objeto mais intuitivo {a: 1}. Sim, isso é estranho, mas você não pode simplesmente mudar o idioma, porque ele faz coisas estranhas. Tudo, exceto as cadeias JSON, é interpretado como JavaScript e avaliado. Digitar 0,
antes de colar o JSON não é difícil; alternativamente, eu ficaria feliz com um aviso de que a string foi interpretada como um objeto em vez de JavaScript por conveniência.
var e = {}; e.toString()
e você verá o que quero dizer