Tipos de datos primitivos

Tipos de datos primitivos en JavaScript

debil tipado

En JavaScript no se requiere definir el tipo de la variable al momento de declararla. Solo basta con utilizar alguna de las palabras reservadas para declarar una variable: var, let, const

1
let miVariable = 'Holus :)';

En este ejemplo declaramos la variable miVariable y la inicializamos con el valor ‘Holus :)’

tipado dinamico

JavaScript resuelve dinámicamente el tipado en tiempo de ejecución. Para comprobar esto podemos utilizar el operador typeof para evaluar el tipo de dato y podríamos hacer algo como lo siguiente

1
2
3
4
5
6
7
let miVariable = 'Holus :)'

console.log(typeof miVariable) // output> string

miVariable = 123

console.log(typeof miVariable) // output> number

Como se puede ver, en tiempo de ejecución JavaScript resuelve dinámicamente el tipo de miVariable

Otro ejemplo es cuando sumamos un string con un number:

1
2
3
4
5
let miVariableStr = '1';

let miVariableNum = 1

console.log(miVariableStr + miVariableNum) // output> '11'

Pero, !¿qué ha pasado?! dinámicamente el motor de JavaScript resolvió los tipos variable para ejecutar la operación solicitada. En este caso concatenó ambas variables como si se trataran de dos strings.

caracteristicas

Los tipos de datos primitivos en javascript no poséen propiedades ni métodos (en javascript todo es un objeto menos los primitivos) y son inmutables.

Ahora bien, para dar un ejemplo de qué es le inmutabilidad primero deberíamos hacer una aclaración. Dijimos que los tipos de datos primitivos no tienen métodos, pero podemos hacer cosas como

1
2
3
let miVariable = 'perro'

console.log(miVariable.toUpperCase()) // output> 'PERRO'

La aclaración es necesaria, surje la pregunta del ejemplo de por qué podemos usar el método toUpperCase() si dijimos que el string es un tipo de dato primitivo y consecuentemente no debería tener métodos.

Pues bien, lo que ocurre es que el motor de javascript crea temporalmente un object wrapper, un objeto temporal que envuelve a un primitivo, en este caso con el objeto del tipo String. Esto se implementa para la mayoría de los primitivos aunque no para todos (los precisaremos más adelante).

Hecha la aclaración hablemos de qué es la inmutablidad. En el ejemplo de arriba vimos como imprimimos nuestra variable en mayúscula con el método toUpperCase, ¿pero esto hizo mutar realmente a nuestro primitivo? veamos qué pasa si lo volvemos imprimir

1
2
3
4
5
let miVariable = 'perro'

console.log(miVariable.toUpperCase()) // output> 'PERRO'

console.log(miVariable) // output> 'perro'

Como podemos ver miVariable no mutó, pudimos imprimirlo en la linea 3 en mayúscula gracias al object wrapper mencionado, pero este es temporal, desaparece y nuestro tipo primitivo de dato no ha mutado, veamos un ejemplo mas

1
2
3
4
5
6
7
8
let miVariable = 'perro'

console.log(miVariable[0]) // output> 'p'

miVariable[0] = 'c'

console.log(miVariable[0]) // output> 'p'

En este último ejemplo intento mutar miVariable cambian la primer letra de mi string y no puedo, pues estamos en la misma situación, si puedo acceder a la primer letra es gracias al object wrapper pero es algo temporal que ha resuelto dinámicamente javascript, por lo que nuestro primitivo no muta.

Claramente puedo asignarle un nuevo valor a mi variable y como vimos también cambiar el tipo pero esto no tiene nada que ver con mutabilidad sino que estamos modificando el valor en memoria al que apunta la variable.

tipos de datos primitivos

En javascript hay siete tipos de primitivos:

string

En la mayoría de los ejemplos ya estuvimos trabajando con string. Los string se definen entre comillas. Estas pueden ser dobles, simples o backticks

1
2
3
4
5
6
7
8
9
10
11
let primString1 = "gato"

console.log(typeof primString1) // output> string

let primString2 = 'gato'

console.log(typeof primString2) // output> string

let primString3 = `gato`

console.log(typeof primString3) // output> string

number

En javascript para el tipo number da igual si es un entero, negativo, decimal con lo cual podemos hacer

1
2
3
4
5
6
7
8
9
10
11
let primNumber1 = 123

console.log(typeof primNumber1) // output> number

let primNumber2 = -321

console.log(typeof primNumber2) // output> number

let primNumber3 = 3.14

console.log(typeof primNumber3) // output> number

En javascript había una limitante al momento de trabajar con números existía un máximo y un mínimo, que pasados estos valores los resultados eran imprecisos, por no decir locos, podemos conocerlos

1
2
3
console.log(Number.MAX_SAFE_INTEGER)  // output> 9007199254740991

console.log(Number.MIN_SAFE_INTEGER) // output> -9007199254740991

Como esto era un buen punto de mejora vino el siguiente primitivo a resolver ese problema

bigint

Con bigint (el más flamante primitivo incorporado en javascript) podemos emplear números de longitud arbitraria sin limitación, lo podemos emplear de diferentes modos, agregándole un n al final del número o pasándo sea un número o un string como argumento a BigInit()

1
2
3
4
5
6
7
8
9
10
11
let primBigInt1 = 123n

console.log(typeof primBigInt1) // output> bigint

let primBigInt2 = BigInt('123')

console.log(typeof primBigInt2) // output> bigint

let primBigInt3 = BigInt(123)

console.log(typeof primBigInt3) // output> bigint

boolean

Este tipo de dato primitivo tiene solo dos valores posibles: true o false

1
2
3
4
5
6
7
let primBool1 = true

console.log(typeof primBool1) // output> boolean

let primBool2 = false

console.log(typeof primBool2) // output> boolean

symbol

Symbol es un primitivo que genera valores únicos. El symbol puede ser creado con una descripción e incluso dos symbols con las misma descripción son diferentes

1
2
3
4
5
6
7
8
9
10
11
let primSymbol1 = Symbol()

console.log(typeof primSymbol1) // output> symbol

let primSymbol2 = Symbol('descripcion')

console.log(typeof primSymbol2) // output> symbol

let primSymbol3 = Symbol('descripcion')

console.log(primSymbol2 === primSymbol3) // output> false

undefined

Este tipo de dato primitivo es automáticamente asignado a las variables que sean declaradas sin una inicialización

1
2
3
4
5
6
7
let primUndefined1 = undefined

console.log(typeof primUndefined1) // output> undefined

let primUndefined2

console.log(typeof primUndefined2) // output> undefined

null

Si apelamos a la definición de tipo dato primitivo, es decir que no posée método ni propiedades y es inmutable, pero al evaluar el tipo con el operador typeof nos devuelve object. Lo que resulta un bug propio del lenguaje

1
2
3
let primNull1 = null

console.log(typeof primNull1) // output> object

*Hemos mencionado las bondades del object wrapper y hemos dicho que no se aplica a todos los tipos de valores primitivos, undefined y null son los primitivos que no poséen object wrapper.