TLDR: Oblígate a usar triples iguales.
Sin querer encontré este meme de JavaScript en Reddit, y es el mejor que he visto en mi vida.
Puede verificar la precisión de este meme ejecutando cada fragmento de código en Herramientas para desarrolladores. El resultado no es sorprendente, pero sí decepcionante.
Por supuesto, este pequeño experimento me llevó a preguntarme ...
¿Por qué pasó esto?
Con experiencia, he aprendido a abrazar los lados suaves de JavaScript mientras admiro sus espinosos pinos. No obstante, los detalles de este caso de la esquina todavía me afectaron.
Es como dice Kyle Simpson ...
"No creo que nadie conozca realmente a JS, al menos no del todo".
Cuando aparecen estos casos, es mejor consultar la fuente: la especificación oficial de ECMAScript a partir de la cual se construye JavaScript.
Con la especificación en la mano, entendamos profundamente lo que está sucediendo aquí.
Panel 1: Introducción a la coerción
Si lo ejecuta 0 == "0"
en su consola de desarrollador, ¿por qué vuelve true
?
0
es un número y "0"
es una cadena, ¡nunca deberían ser iguales! La mayoría de los lenguajes de programación respetan eso. 0 == "0"
en Java, por ejemplo, devuelve esto:
error: incomparable types: int and String
Esto tiene mucho sentido. Si desea comparar un int y String en Java, primero debe convertirlos al mismo tipo.
¡Pero esto es JavaScript, todos ustedes!
Cuando compara dos valores mediante ==
, uno de los valores puede sufrir coerción .
Coerción: cambiar automáticamente un valor de un tipo a otro.
Automáticamente es la palabra clave aquí. En lugar deconvertir explícitamente sus tipos, JavaScript lo hace por usted detrás de escena.
Esto es conveniente si lo está explotando a propósito, pero potencialmente dañino si no conoce sus implicaciones.
Aquí está la especificación oficial del lenguaje ECMAScript al respecto. Parafrasearé la parte relevante:
Si x es Número e y es Cadena, devuelve x == ToNumber (y)
Entonces, para nuestro caso de 0 == "0"
:
Dado que 0 es Número y "0" es Cadena, devuelve 0 == ToNumber ("0")
Nuestra cadena "0"
se ha convertido en secreto 0
, ¡y ahora tenemos una coincidencia!
0 == "0" // true // The second 0 became a number! // so 0 equals 0 is true....
Extraño, ¿verdad? Bueno, acostúmbrate, ni siquiera hemos terminado a la mitad.
Panel 2 - Las matrices también se fuerzan
Esta tontería no se limita a primitivas como cadenas, números o booleanos. Aquí está nuestra próxima comparación:
0 == [] // true // What happened...?
¡Coacción de nuevo! Parafrasearé la parte relevante de la especificación:
Si x es String o Number e y es Object, devuelve x == ToPrimitive (y)
Tres cosas aquí:
1. Sí, las matrices son objetos
Lamento romperlo.
2. La matriz vacía se convierte en una cadena vacía
Nuevamente, de acuerdo con la especificación, JS primero busca el toString
método de un objeto para coaccionarlo.
En el caso de las matrices, toString
une todos sus elementos y los devuelve como una cadena.
[1, 2, 3].toString() // "1,2,3" ['hello', 'world'].toString() // "hello,world"
Dado que nuestra matriz está vacía, ¡no tenemos nada a lo que unirnos! Por lo tanto...
[].toString() // ""
La especificación ToPrimitive
convierte esta matriz vacía en una cadena vacía. Las referencias están aquí y aquí para su conveniencia (o confusión).
3. La cadena vacía se convierte en 0
No puedes inventar estas cosas. Ahora que hemos coaccionado a la matriz ""
, volvemos al primer algoritmo ...
Si x es Número e y es Cadena, devuelve x == ToNumber (y)
Así que para 0 == ""
Como 0 es Número y "" es Cadena, devuelve 0 == ToNumber ("")
ToNumber("")
devuelve 0.
Por eso, 0 == 0
una vez más ...
Panel 3 - Resumen rápido
Esto es verdad
0 == "0" // true
Porque la coerción convierte esto en 0 == ToNumber("0")
.
Esto es verdad
0 == [] // true
Porque la coerción se ejecuta dos veces:
ToPrimitive([])
da cuerda vacía- Entonces
ToNumber("")
da 0.
Entonces dime ... de acuerdo con las reglas anteriores, ¿qué debería devolver esto?
"0" == []
Panel 4 - ¡FALSO!
¡FALSO! Correcto.
Esta parte tiene sentido si entendiste las reglas.
Aquí está nuestra comparación:
"0" == [] // false
Haciendo referencia a la especificación una vez más:
Si x es String o Number e y es Object, devuelve x == ToPrimitive (y)
Eso significa...
Como "0" es String y [] es Object, devuelve x == ToPrimitive ([])
ToPrimitive([])
devuelve una cadena vacía. La comparación se ha convertido ahora
"0" == ""
"0"
y ""
son ambas cadenas, por lo que JavaScript dice que no se necesita más coerción . Es por eso que obtenemos false
.
Conclusión
Use triples iguales y duerma profundamente por la noche.
0 === "0" // false 0 === [] // false "0" === [] // false
Evita la coerción por completo, ¡así que supongo que también es más eficiente!
Pero el aumento de rendimiento casi no tiene sentido. La verdadera ventaja es la mayor confianza que tendrá en su código, lo que hace que valga la pena esa pulsación adicional.
¿Quieres coaching gratuito?
Si desea programar una llamada gratuita de 15 a 30 minutos para discutir preguntas sobre el desarrollo de Front-End con respecto al código, entrevistas, carrera o cualquier otra cosa, sígame en Twitter y envíeme un mensaje de correo electrónico.
Después de eso, si disfruta de nuestra primera reunión, ¡podemos discutir una relación de coaching continua que lo ayudará a alcanzar sus objetivos de desarrollo de Front-End!
Gracias por leer
Para obtener más contenido como este, visite //yazeedb.com.
¡Hasta la proxima vez!