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