-
-
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('{} + {}')
NaNJá 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 :)