Só um detalhe: os 3 primeiros itens não são exclusividade do JavaScript. Eles são todos consequências do padrão IEEE 754, e afetam outras linguagens que usam este padrão (como por exemplo C, Java, C#, etc).
No caso do NaN
, apesar do nome que pode confundir ("not a number", mas é um "valor númerico"), é um valor válido e definido pela norma. Inclusive, o fato dele não ser igual a nenhum outro valor (nem ele mesmo) é totalmente arbitrário, mas existe um raciocínio por trás, explicado em mais detalhes aqui.
Sobre o segundo caso, ver a explicação aqui.
E sobre o terceiro caso, é o motivo pelo qual números de ponto flutuante não são o tipo mais adequado para operações financeiras (um erro infelizmente comum). Sobre isso, ver mais detalhes aqui, aqui, aqui, aqui e aqui.
Quanto aos outros casos, eles podem ser explicados pelas regras malucas de coerção automática. Basicamente, cada operador (como o +
, ==
, etc) verifica o tipo dos seus operandos, e dependendo do caso, converte-os para alguma outra coisa antes de fazer a operação. Para saber as regras exatas, sugiro consultar a especificação oficial da linguagem.
O problema, claro, é que isso gera esses resultados absurdos. O lado bom é que também gerou um dos melhores vídeos sobre a linguagem :-)