Create a gist now

Instantly share code, notes, and snippets.

@leobalter /zofe.js
Last active Apr 14, 2017

What would you like to do?
Qual o resultado para:
// 1:
{}+{} // ?
// 2:
({}+{}) // ?

thotty commented Apr 20, 2016

Com o 'eval()` no Node.JS retorna o esperado :)

  • Imagino que no eval ele usa direto o V8, né?
eval('{}') //undefined
eval('+{}') //NaN
eval('{}+{}') //NaN
eval('({})') //{}
eval('(+{})') //NaN
eval('({}+{})') //'[object Object][object Object]'

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

Owner

leobalter commented Apr 14, 2017

> {}+{}
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment