A transitividade da igualdade do JavaScript é estranha

Eu tenho lido o JavaScript de Douglas Crockford : The Good Parts , e me deparei com esse estranho exemplo que não faz sentido para mim:

'' == '0' // false 0 == '' // true 0 == '0' // true false == undefined // false false == null // false null == undefined // true 

O autor também menciona “nunca usar == e != . Em vez disso, use sempre === e !== “. No entanto, ele não explica porque o comportamento acima é exibido? Então, minha pergunta é: por que os resultados acima estão como estão? A transitividade não é considerada em JavaScript?

 '' == '0' // false 

O lado esquerdo é uma string vazia, e o lado direito é uma string com um caractere. Eles são falsos porque está fazendo uma comparação entre duas cadeias idênticas (obrigado Niall ).

 0 == '' // true 

Por isso, porque este é verdadeiro, porque 0 é falso e a corda vazia é falsa .

 0 == '0' // true 

Este é um pouco mais complicado. A especificação informa que, se os operandos são uma string e um número, então coagere a string para number. '0' se torna 0 . Obrigado smfoote .

 false == undefined // false 

O valor undefined é especial em JavaScript e não é igual a nada, exceto null . No entanto, é falsamente .

 false == null // false 

Novamente, null é especial. É apenas igual a undefined . Também é falso .

 null == undefined // true 

null e undefined são semelhantes, mas não iguais. null significa nada , enquanto undefined é o valor de uma variável não definida ou não existente. Seria meio que fazer sentido que seus valores fossem considerados iguais.

Se você quer estar realmente confuso, verifique isso …

 '\n\r\t' == 0 

Uma string que consiste apenas em espaços em branco é considerada igual a 0.

Douglas Crockford faz muitas recomendações, mas você não precisa tomá-las como um evangelho. 🙂

TJ Crowder faz uma excelente sugestão de estudar a especificação da linguagem ECMAScript para conhecer toda a história por trás desses testes de igualdade.

Leitura adicional?

A especificação

yolpo (em valores falsos)

A resposta a essa pergunta tem a ver com como o JavaScript lida com a coerção. No caso de == , as cadeias são coagidas para números . Assim sendo:

'' == '0' é equivalente a '' === '0' (ambos são strings, portanto, nenhuma coerção é necessária).

0 == '' é equivalente a 0 === 0 porque a string '' se torna o número 0 ( math.abs('') === 0 ).

0 == '0' é equivalente a 0 === 0 pelo mesmo motivo.

false == undefined equivale a 0 === undefined porque o JavaScript faz com que booleans sejam números quando os tipos não coincidem

false == null é equivalente a 0 === null pelo mesmo motivo.

null == undefined é verdadeiro porque a especificação diz isso.

Obrigado por fazer esta pergunta. Minha compreensão de == é muito melhor por ter pesquisado isso.

Na verdade, você pode escrever uma function JavaScript que se comporta exatamente como == que deve lhe dar algumas dicas sobre como ela se comporta.

Para mostrar o que quero dizer aqui é essa function:

 // loseEqual() behaves just like `==` function loseEqual(x, y) { // notice the function only uses "strict" operators // like `===` and `!==` to do comparisons if(typeof y === typeof x) return y === x; if(typeof y === "function" || typeof x === "function") return false; // treat null and undefined the same var xIsNothing = (y === undefined) || (y === null); var yIsNothing = (x === undefined) || (x === null); if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing); if(typeof x === "object") x = toPrimitive(x); if(typeof y === "object") y = toPrimitive(y); if(typeof y === typeof x) return y === x; // convert x and y into numbers if they are not already use the "+" trick if(typeof x !== "number") x = +x; if(typeof y !== "number") y = +y; return x === y; } function toPrimitive(obj) { var value = obj.valueOf(); if(obj !== value) return value; return obj.toString(); } 

Como você pode ver, == tem muita lógica complicada para conversão de tipo. Por causa disso, é difícil prever qual resultado você obterá.

Aqui estão alguns exemplos de alguns resultados que você não esperaria:

Verdades inesperadas

 [1] == true // returns true '0' == false // returns true [] == false // returns true [[]] == false // returns true [0] == false // returns true '\r\n\t' == 0 // returns true 

Conclusões Inesperadas

 // IF an empty string '' is equal to the number zero (0) '' == 0 // return true // AND the string zero '0' is equal to the number zero (0) '0' == 0 // return true // THEN an empty string must be equal to the string zero '0' '' == '0' // returns **FALSE** 

Objetos com Funções Especiais

 // Below are examples of objects that // implement `valueOf()` and `toString()` var objTest = { toString: function() { return "test"; } }; var obj100 = { valueOf: function() { return 100; } }; var objTest100 = { toString: function() { return "test"; }, valueOf: function() { return 100; } }; objTest == "test" // returns true obj100 == 100 // returns true objTest100 == 100 // returns true objTest100 == "test" // returns **FALSE** 

A razão é que identidade ou operador estrito (===), ele compara com nenhuma conversão de tipo, isso significa que se ambos os valores não tiverem o mesmo valor e o mesmo tipo, eles não serão considerados iguais.

dê uma olhada neste link, te tira da dúvida: maneira fácil de entender como funciona o operador de identidade

Intereting Posts