Si eres programador seguro que alguna vez has utilizado JavaScript, aunque sea para pequeñas funciones o mini proyectos. Lo que puede que no sepas es que hay ciertos comportamientos que te podrían resultar extraños o que no son intuitivos para los desarrolladores.
Este sería un ejemplo de lo que os hablo:
'1' + 1 --> "11"
'1' - 1 --> 0
JavaScript. Extraño y hermoso al mismo tiempo, es seguramente el lenguaje de programación que habría inventado Pablo Picasso.
Nulo es un objeto
Empecemos con una de las peculiaridades más conocidas de JavaScript: la naturaleza de null. Aunque null debería representar la ausencia total de valor, en JavaScript se identifica como un objeto, lo que genera cierta confusión. Es contradictorio, ¿verdad? ¿Cómo puede null ser un objeto cuando su propósito es justamente representar la ausencia de cualquier valor significativo? Sin embargo, así es como funciona JavaScript. Aquí tienes la prueba:
A pesar de que null se clasifica como un objeto, no se considera una instancia de ningún objeto. En JavaScript, los valores son instancias de objetos base; por ejemplo, cada número es una instancia del objeto Number, y cada objeto es una instancia del objeto Object. Afortunadamente, en este caso, la lógica se mantiene: dado que null representa la ausencia de valor, no puede ser una instancia de nada. Por eso, la siguiente evaluación es falsa:
NaN es un número
Si ya el null te empezaba a romper la cabeza, el NaN te la va a terminar de romper del todo. NaN, proviene del acrónimo en inglés «Not a Number» (en español: no es un número). Esto debería hacerte pensar que si comprobamos el tipo «typeof NaN
«, nos debería indicar que no es un número, pero no es así. Aquí el ejemplo:
Además, NaN no se considera ni siquiera igual a sí mismo. De hecho no NaN es igual a nada . La única forma de confirmar que algo es NaN a través de la función isNaN().
Un array sin claves es FALSE
Esta es la comprobación que se puede hacer para demostrar el concepto:
new Array() == false
–> Esto da como resultado true
Para entender lo que sucede aquí, es crucial familiarizarse con los conceptos de «verdad» y «falsedad» en JavaScript. Estos términos se refieren a cómo ciertos valores se comportan como verdaderos o falsos en contextos booleanos, algo que puede resultar confuso, especialmente si tienes experiencia en lógica formal o filosofía.
He leído varias explicaciones sobre qué significan estos términos, y la que considero más clara es esta: en JavaScript, cada valor no booleano tiene una propiedad booleana implícita que se activa cuando se le pide que se comporte como un booleano. Esto ocurre, por ejemplo, cuando comparas ese valor con un booleano.
Dado que no se pueden comparar directamente manzanas con peras, cuando JavaScript necesita comparar valores de diferentes tipos de datos, primero los «convierte» a un tipo de dato común. Valores como false, 0, null, undefined, cadenas vacías y NaN se convierten en false, pero solo dentro de la expresión en cuestión. Aquí tienes un ejemplo:
var someVar = 0;
alert(someVar == false); // se evalúa como true
En este caso, estamos comparando el número 0 con el booleano false. Dado que estos tipos de datos son incompatibles, JavaScript convierte internamente 0 a su equivalente booleano, que es false.
Quizás hayas notado que no mencioné las matrices vacías en la lista de valores «falsos» anterior. Las matrices vacías son casos curiosos: en realidad, se evalúan como verdaderas, pero cuando se comparan con un booleano, se comportan como si fueran falsas. ¿Confuso? Con razón. Aquí tienes otro ejemplo:
var someVar = []; // array vacío
alert(someVar == false); // se evalúa como true
if (someVar) alert('hello'); // se ejecuta el alert, así que someVar se evalúa como true
Para evitar este tipo de conversiones automáticas, puedes utilizar el operador de comparación estricta (===), que compara tanto el valor como el tipo de dato, a diferencia de ==, que solo compara valores. Así:
var someVar = 0;
alert(someVar == false); // se evalúa como true – cero es un valor falso
alert(someVar === false); // se evalúa como false – cero es un número, no un booleano
Este tema es extenso y recomiendo investigar más sobre la coerción de datos, que, aunque no es un concepto exclusivo de JavaScript, es especialmente relevante en este lenguaje. Si te interesa profundizar en cómo JavaScript maneja estas comparaciones internamente, te sugiero consultar la sección 11.9.3 de la especificación ECMA-262.