Primeiro, deixe-me salientar que NaNé um valor muito especial: por definição, não é igual a si mesmo. Isso vem do padrão IEEE-754 que os números JavaScript utilizam. O valor "não é um número" nunca é igual a si mesmo, mesmo quando os bits são uma correspondência exata. (Que eles não estão necessariamente no IEEE-754, ele permite vários valores diferentes de "não é um número".) É por isso que isso acontece; todos os outros valores em JavaScript são iguais a eles mesmos, NaNé apenas especial.
... estou perdendo algum valor no JavaScript que retornará verdadeiro para x! == xe falso para x! = x?
Não, você não é. A única diferença entre !==e !=é que este último fará a coerção de tipos, se necessário, para obter os tipos dos operandos iguais. Em x != x, os tipos dos operandos são os mesmos e, portanto, são exatamente os mesmos que x !== x.
Isso fica claro desde o início da definição da Operação de Igualdade Abstrata :
- ReturnIfAbrupt (x).
- ReturnIfAbrupt (y).
Se o Tipo (x) for igual ao Tipo (y), então
Retorne o resultado da realização de Comparação Rigorosa de Igualdade x === y.
...
Os dois primeiros passos são o encanamento básico. Portanto, com efeito, o primeiro passo ==é verificar se os tipos são iguais e, se for o caso, fazê-lo ===.!=e !==são apenas versões negadas disso.
Portanto, se Flanagan estiver correto, que somente NaNdará verdade para x !== x, podemos ter certeza de que também é verdade que somente NaNdará para x != x.
Muitos programadores de JavaScript usam o padrão ===e !==evitam algumas armadilhas em torno da coerção de tipo que os operadores soltos fazem, mas não há nada para ler sobre o uso de Flanagan do operador estrito versus frouxo neste caso.
!==cheques sobre!=cheques. Tanto quanto sei, não há outro valor em quex != x. Mas existem dois grupos distintos de desenvolvedores de JavaScript: aqueles que preferem!=e aqueles que preferem!==, seja por velocidade, clareza, expressividade etc.