w3schools tag tab style page for color javascript comparison-operators equivalence transitivity

tag - JavaScript transitivity igualdad es raro



title of page html (4)

He estado leyendo el JavaScript de Douglas Crockford : The Good Parts , y me encontré con este extraño ejemplo que no tiene sentido para mí:

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

El autor también menciona "nunca usar == y != . En cambio, siempre use === y !== ". Sin embargo, él no explica por qué se exhibe el comportamiento anterior. Entonces mi pregunta es, ¿por qué son los resultados anteriores como son? ¿No se considera transitividad en JavaScript?


En realidad, puede escribir una función de JavaScript que se comporte exactamente igual que == que debería proporcionarle una idea de cómo se comporta.

Para mostrarte lo que quiero decir aquí está esa función:

// 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 puede ver, == tiene mucha lógica complicada para la conversión de tipos. Por eso es difícil predecir qué resultado obtendrás.

Estos son algunos ejemplos de algunos resultados que no esperarías:

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

Conclusiones 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 con funciones especiales

// 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**



La respuesta a esta pregunta tiene que ver con cómo JavaScript maneja la coerción. En el caso de == , las cadenas se fuerzan para ser números . Por lo tanto:

'''' == ''0'' es equivalente a '''' === ''0'' (ambos son cadenas, por lo que no es necesaria la coacción).

0 == '''' es equivalente a 0 === 0 porque la cadena '''' convierte en el número 0 ( math.abs('''') === 0 ).

0 == ''0'' es equivalente a 0 === 0 por la misma razón.

false == undefined equivale a 0 === undefined porque JavaScript fuerza a los booleanos a ser números cuando los tipos no coinciden

false == null es equivalente a 0 === null por la misma razón.

null == undefined es verdadero porque la especificación así lo dice.

Gracias por hacer esta pregunta. Mi comprensión de == es mucho mejor por haberlo investigado.


'''' == ''0'' // false

El lado izquierdo es una cadena vacía, y el lado derecho es una cadena con un caracter. Son falsos porque está haciendo una comparación entre dos cadenas idénticas (gracias Niall ).

0 == '''' // true

Por lo tanto, por qué este es verdadero, porque 0 es falso y la cadena vacía es falso .

0 == ''0'' // true

Este es un poco más complicado. La especificación establece que si los operandos son una cadena y un número, entonces fuerza la cadena al número. ''0'' convierte en 0 . Gracias smfoote .

false == undefined // false

El valor undefined es especial en JavaScript y no es igual a nada más que null . Sin embargo, es falso .

false == null // false

Nuevamente, null es especial. Solo es igual a undefined . También es falso .

null == undefined // true

null e undefined son similares, pero no son lo mismo. null no significa nada , mientras que undefined es el valor para una variable no establecida o no existente. Tendría sentido que sus valores se consideren iguales.

Si quieres estar realmente confundido, mira esto ...

''/n/r/t'' == 0

Una cadena que consta únicamente de espacios en blanco se considera igual a 0.

Douglas Crockford hace muchas recomendaciones, pero no tiene que tomarlas como un evangelio. :)

TJ Crowder hace una excelente sugerencia de estudiar la ecma-international.org/publications/standards/Ecma-262.htm para conocer toda la historia detrás de estas pruebas de igualdad.

¿Otras lecturas?

La especificación

yolpo (en los valores falsy)