Todos los lenguajes de programación necesitan manejar diferentes tipos de datos. Dentro de esos tipos de datos existen: texto, números, booleanos, etc. A veces más, a veces menos dependiendo de cada lenguaje.
Pero adicionalmente a esos tipos de datos se necesita la capacidad de representar la falta de valor, de definición. En Javascript esto se maneja con los tipos de dato null
y undefined
.
¿Pero por qué 2 tipos de datos para este propósito?
Otros lenguajes solo utilizan 1 concepto para representar la ausencia de valor:
- En Python se utiliza
None
. - En PHP existe
NULL
. - En Java se utiliza
null
(aunque no lo consideran un tipo de dato).
Sin embargo en Javascript hay 2. ¿Por qué? ¿Cuál es la diferencia entre null
y undefined
?
Probablemente te haz topado con una imagen similar a la siguiente.
Esta imagen es una buena representación de la diferencia, aunque igual necesita un poco de explicación.
null
representa la ausencia de un valor de manera intencional.undefined
representa que no se ha asignado un valor.
Sin embargo esto no te dice mucho de como utilizar ambos valores en código. Ambos representan que no hay valor, pero la incógnita sigue: ¿Cuando usamos uno y cuando usamos otro?
Primero que nada tienes que tener claras las diferencias de comportamiento entre ambas.
Las diferencias
Tipos de dato
null
y undefined
son tipos de datos primitivos en Javascript, así como Number
, Boolean
o String
. Esto da pie a pensar que entonces el tipo de dato de null
y undefined
pues es igual a ellos mismos.
Esto lo puedes corroborar con typeof
.
typeof(null) // object
typeof(undefined) // undefined
undefined
si cumple con las expectativas, pero null
no. ¿Por qué pasa esto?
La respuesta probablemente no te satisfaga, pero esto es considerado como un error.
Así es. El lenguaje de programación de Javascript tiene errores. ¿Por qué no se corrige?
JS tiene el propósito de ser retrocompatible. Esto es por que hay muchos sitios en la web que estan hechos con versiones previas del lenguaje. Si se hicieran cambios que anularan comportamientos anteriores se podrían afectar el funcionamiento y romper varios sitios.
Esto significa que nos toca vivir con los errores del pasado.
Coerción Implícita
La coerción implícita se refiere al proceso de conversión entre diferentes tipos de datos dependiendo del contexto.
null
Tipo de Conversión | Valor representado |
Boolean | false |
Number | 0 |
undefined
Tipo de Conversión | Valor representado |
Boolean | false |
Number | NaN |
*Coerción Implícita es un tema más grande que esto. Puedes aprender más acerca de este proceso aquí.
Ejemplo
Con estas diferencias en mente, veamos como difiere null
y undefined
en el escenario más común:
null
async function fiilFormOptions (newEnrollment) {
let enrolledDate = null
let studentProfile = null
let lastSelectedCourse = null
if (!newEnrollment) {
enrolledDate = await fetch('someUrl/1')
studentProfile = await fetch('someUrl/2')
lastSelectedCourse = await fetch('someUrl/3')
if (enrolledDate === null) {
throw Error('Error retrieving enrolledDate')
}
}
}
undefined
async function fiilFormOptions (newEnrollment) {
let enrolledDate = undefined
let studentProfile = undefined
let lastSelectedCourse = undefined
if (!newEnrollment) {
enrolledDate = await fetch('someUrl/1')
studentProfile = await fetch('someUrl/2')
lastSelectedCourse = await fetch('someUrl/3')
if (enrolledDate === undefined) {
throw Error('Error retrieving enrolledDate')
}
}
}
Como puedes ver es exactamente el mismo código y no cambia nada en la lógica o en el funcionamiento. Así que si se usan de la misma manera…entonces… ¿podríamos usarlos indiferentemente? ¿como si fueran lo mismo? Eso tampoco es del todo cierto tristemente. Recuerda lo que viste en la sección de Coerción Implícita.
null === undefined; // false
Bueno, entonces ¿de qué sirve usar uno u otro?
Hay algo en lo que te puede ayudar , pero es más debido a una buena práctica que por que sea alguna funcionalidad que te ofrece Javascript.
La utillidad de null
y undefined
Cuando declaras una variable, Javascript siempre la inicializa con el valor de undefined
.
let value; // undefined
Este es el comportamiento default de Javascript y no hay ningun escenario en el que se haga lo mismo con null
.
De hecho puedes recordar la definición de null
, al inicio de este post:
null
representa la ausencia de un valor de manera intencional.
Por lo tanto te invitó a que adoptes la siguiente buena práctica:
Cuando necesites asignar explícitamente la ausencia de valor, hazlo con null
. Tu como desarrollador jamás asignes undefined
.
¿En qué te ayuda esto?
Si sigues esta regla, en el momento en el que te encuentres con un undefined
sabrás que hay un error en la lógica de tu código, ya que dicha variable jamás tuvo un valor asignado por ti.
En cambio cuando te encuentres un null
sabrás que dicha variable no tiene valor por una decisión consciente que hiciste como desarrollador.
Obviamente al ser solo una buena práctica y no una característica del lenguaje inevtiablemente te encontrarás con proyectos que no siguen esta regla.
Sin embargo cuando tengas la oportunidad de implementarlo en un proyecto desde el inicio (y mejor aún si puedes establecer la regla en un linter y en una guía de estilos de código) hazlo. De verdad te salvará de mucho tiempo de debuggeo.
Y al final que mejor que utilizar tu tiempo para los bugs realmente importantes.