Métodos en tipos primitivos
Clase 1 de 55 min de lectura
En JavaScript puedes escribir 'hola'.toUpperCase() y funciona a la primera. Pero hay algo que no cuadra: un texto es un primitivo, los primitivos no son objetos… y los métodos son cosa de objetos. Entonces, ¿de dónde sale ese .toUpperCase()?
¿Qué son los tipos primitivos?#
En JavaScript, un primitivo (o primitive) es un dato que no es un objeto y no tiene métodos propios. Hay exactamente 7 tipos primitivos:
string: cadenas de texto.number: números.bigint: números enteros enormes.boolean: verdadero o falso.undefined: valor sin definir.symbol: identificadores únicos.null: ausencia intencionada de valor.
// Estos son todos tipos primitivoslet texto = 'Hola mundo'let numero = 42let grande = 123nlet verdadero = truelet indefinido = undefinedlet simbolo = Symbol('id')let nulo = nullLa paradoja: ¿Cómo pueden los primitivos tener métodos?#
Si los primitivos no son objetos ni tienen métodos, esto no debería funcionar:
let texto = 'JavaScript'console.log(texto.length) // -> 10console.log(texto.toUpperCase()) // -> 'JAVASCRIPT'Y sin embargo funciona: leemos una propiedad y llamamos a un método sobre un primitivo.
Object Wrappers: La magia detrás de escena#
El truco se llama Object Wrapper (objeto envoltorio). Piensa en un papel de regalo de usar y tirar: envuelve tu valor el tiempo justo y después va a la basura.
Cada vez que accedes a una propiedad o un método de un primitivo, JavaScript:
- Crea un objeto temporal que envuelve el valor primitivo.
- Ejecuta el método (o lee la propiedad) en ese objeto.
- Destruye el objeto nada más terminar y te devuelve el resultado.
Con nuestro ejemplo:
let texto = 'JavaScript'// Cuando escribes texto.toUpperCase(), JavaScript hace esto internamente:// 1. Crea: new String("JavaScript")// 2. Llama al método: new String("JavaScript").toUpperCase()// 3. Devuelve el resultado: "JAVASCRIPT"// 4. Destruye el objeto temporallet texto = 'JavaScript'texto.toUpperCase()typeof textotexto.nuevaPropiedad = 'valor'texto.nuevaPropiedadundefined (en modo estricto, error).Demostrando que los primitivos siguen siendo primitivos#
Vale, pero ¿y si texto se ha convertido en objeto por el camino? Tres pruebas de que no. Fíjate sobre todo en la segunda:
// 1. Usando typeoflet texto = 'Hola'console.log(typeof texto) // -> 'string' (no 'object')// 2. Intentando asignar propiedadestexto.nuevaPropiedad = 'valor'console.log(texto.nuevaPropiedad) // -> undefined (¡no se guardó!)// 3. Comparando con objetos realeslet textoObjeto = new String('Hola')console.log(typeof textoObjeto) // -> 'object'console.log(texto === textoObjeto) // -> falseLa propiedad se la pusimos al envoltorio temporal, que desapareció al instante. Al pedirla después, JavaScript crea otro envoltorio distinto, sin rastro de ella.
Los Object Wrappers disponibles#
Cada primitivo tiene su envoltorio, con el mismo nombre pero empezando en mayúscula:
| Primitivo | Object Wrapper |
|---|---|
string | String |
number | Number |
bigint | BigInt |
boolean | Boolean |
symbol | Symbol |
¿Echas de menos a dos? undefined y null no tienen envoltorio. Por eso llamar a un método sobre ellos lanza un error:
let indefinido = undefined// indefinido.toString() // ❌ TypeError: Cannot read properties of undefinedlet nulo = null// nulo.toString() // ❌ TypeError: Cannot read properties of null¿Por qué es importante entender esto?#
Saber que existen los envoltorios te explica tres cosas:
- Rendimiento: conceptualmente, JavaScript crea y destruye un objeto temporal en cada acceso.
- Comportamiento: por eso no puedes guardar propiedades en un primitivo.
- Depuración: entiendes mejor los errores relacionados con tipos, como los de
nullyundefined.
Y pasa igual con cualquier primitivo. Mira un número:
// Esto funcionalet numero = 42console.log(numero.toString()) // -> '42'// Pero esto no guarda la propiedadnumero.nuevaPropiedad = 'valor'console.log(numero.nuevaPropiedad) // -> undefined// Porque cada acceso crea un nuevo objeto temporalPara terminar...#
Los primitivos no son objetos, pero JavaScript te deja tratarlos como si lo fueran gracias a esos envoltorios temporales. En las próximas clases veremos uno a uno los tipos primitivos y sus métodos más útiles.
En resumen
- Los primitivos no son objetos ni tienen métodos propios.
- Al usar un método o una propiedad, JavaScript crea un Object Wrapper temporal, lo usa y lo destruye.
- Por eso no puedes guardar propiedades en un primitivo: se quedan en un envoltorio que ya no existe.
nullyundefinedno tienen wrapper: llamar a un método sobre ellos lanza unTypeError.