-
-
Save leobalter/e7f2fe51263b83a91b7f3e5cdf3ea05a to your computer and use it in GitHub Desktop.
Qual o resultado para: | |
// 1: | |
{}+{} // ? | |
// 2: | |
({}+{}) // ? |
No Node.js 4.5 ou no Chrome/Chromium 53 (os ambientes que eu testei), tenho os seguintes resultados:
> {} + {}
"[object Object][object Object]"
> ({} + {})
"[object Object][object Object]"
> eval('({} + {})')
"[object Object][object Object]"
> eval('{} + {}')
NaN
Já no Firefox 49 tenho o seguinte:
> {}+{}
NaN
> ({}+{})
"[object Object][object Object]"
> eval('{}+{}')
NaN
> eval('({}+{})')
"[object Object][object Object]"
Entendo o resultado de {} + {}
ser NaN
pelo fato do primeiro {}
ser considerado um bloco vazio ao invés de um objeto, o que resulta em +{}
ser NaN
. No outro caso, como temos a operação entre parênteses, ambos os {}
são considerados objetos, o que justifica "[object Object][object Object]"
.
O que não faz sentido pra mim, é {} + {}
retornar a string no Chrome/Chromium e no Node.js, quando está fora do eval()
.
Até falei sobre isso no nesse post: WAT JS - Mergulhando nos Comportamentos do JavaScript.
Se alguém puder dar uma explicação, ficarei muito agradecido.
acredito, @gabsprates que ele esteja fazendo um cast the {}
para string para poder concatenar com o outro {}
.
Seria o equivalente a:
({}).toString() + ({}).toString()
No firefox é NaN
(o que acho que faz mais sentido) por que o casting para string deveria acontecer apenas APÓS o sinal de +
.
Assim como 1+'1'
é "11" mas 1+1
é "2". O chrome está transformando ambos em strings antes de concatenar, enquanto o Firefox está tentando somar dois objetos que "Não são Números".
@felipenmoura então é provável que isso seja um comportamento do V8?
Fiz um teste aqui, acho que o Chrome/Chromium e o Node não tratam esses blocos vazios. Parece que eles consideram objetos mesmo, isso no console.
Se você tentar rodar { foo: 1, bar: 2 }
nesses ambientes, eles retornam um objeto mesmo, já no Firefox, ele tenta executar esse código como um bloco, mas dá erro por causa da falta do ;
.
Acredito que a questão é mesmo o V8 permitir esses objetos no contexto do console, uma vez que um arquivo block.js com o conteúdo { foo: 1, bar: 2 }
, também dá erro quando executado com node block.js
> {}+{}
NaN
> ({}+{})
"[object Object][object Object]"
é o comportamento válido, de acordo com a especificação. O problema de verificar esse código no console do browser é que ele encapsula o código e o {}
pode ser interpretado em posição de expressão, não de statement. Fazendo o valor sair diferente em alguns browsers. O mesmo acontece no node.
Com o 'eval()` no Node.JS retorna o esperado :)