data types en js

Guía básica sobre los data types en JavaScript

Última actualización:

En JavaScript existen diferentes tipos de datos, clasificados en 7 categorías. Dentro de una categoría existe una sub-categoría llamada reference types, pero nos encargaremos de eso más adelante.

Todos los data types tienen sus propiedades únicas y métodos específicos.  

Tabla-resumen data types

data type

¿qué son?

Number

Son números de toda la vida, tanto enteros como decimales.

const myNumber = 8;

String

Son caracteres, letras o cualquier cosa que vaya entre comillas, tanto simples como dobles, eso es a criterio tuyo. 

const myString = 'women in tech!' const email = 'contacto@acontracorrientech.com';

Boolean

Caracteres de lógica. 

 

Pueden tomar dos valores (true false). 

 

Se usan para evaluar condiciones y ver si son ciertas o no. 

const isSunny = true; console.log(isSunny); // true

Null

Utilizado para expresar explícitamente que una variable no tiene ningún valor asignado. 

 

Está muy relacionado con el data type undefined, con la diferencia de que para que una variable tenga el valor de null deberemos asignárselo nosotros manualmente. 

 

Dato curioso: si utilizamos una variable al que le hayamos dado el valor de null combinada con alguna fórmula matemática, null tomará el valor de 0. 

const street = null; console.log(street); // null let age = null; console.log(age + 8); // 8

Undefined

Una variable es undefined cuando no le hemos dado ningún valor, así que nuestro navegador le atribuye automáticamente el valor de undefined. 

 

Tanto null como undefined son valores vacíos. 

 

Un detallito: las variables const deben ser inicializadas cuando se declaran. Si no, te dará un syntax error. 

 

De ahí que utilice let para este ejemplo. 

let age; console.log(age); // undefined

Object

Son estructuras de datos complejas, que pueden tener múltiples propiedades, funciones, etc. 

 

Aquí nos metemos en un tipo de tipos (aka reference types), ya que existen muchos tipos de objetos dentro de este data typecomo Arrays, Functions, Dates, sets (disponible próximamente) etc. 

const myObj = { name: 'Joey', lastName: 'Tribianni', age: 32 };

Symbol


ES6

Su característica principal es que son únicos, lo que los hace muy valiosos de cara a asociarlos con un único identificador.  

const symbOne = Symbol();

Strings

Métodos más comunes de los​ strings

Un method es una función asociada a un data type en concreto.  Vamos a verlos asociados a los strings. 

método

¿qué hacen?

.lastIndexOf(‘ ‘) 

Identifica la última posición del caracter que le pasemos como argumento. 

.slice(n,n) 

Le pasamos dos parámetros numéricos. El primero indica desde qué posición queremos cortar la string y el último, hasta dónde queremos cortarla.  

.substr(n,n) 

El primer parámetro indica desde dónde queremos empezar a cortar nuestro string, el segundo, cuántos caracteres queremos que imprima. 

.replace(‘x’, ‘y’) 

Admite dos parámetros. El primero es buscado en la string y sustituido por el segundo. Solamente reemplaza la PRIMERA instancia del primer parámetro que encuentre.


Ejemplo (hecho en la consola de chrome): 

let myString = 'central perk'; myString.replace('e', 'x'); // "cxntral perk"

El replace es muy útil combinado con regular expressions. Ejemplo:

let myPassword = 'superSecret123'; myPassword = myPassword.replace(/[a-zA-Z1-9]/gi, '*'); // "**************"

.trim()


🧹

Sirve para eliminar los espacios en blanco antes y después de un string.

 Muy útil por ejemplo para corregir errores del usuario cuando escribe su contraseña en un formulario y teclea por error un espacio en blanco al principio o al final.

let myPassword = ' superSecret123'; // " superSecret123" myPassword.trim(); // "superSecret123"

Numbers

JavaScript nos permite hacer operaciones matemáticas, desde la más simple a la más compleja.  

En javaScript, como en matemáticas, el orden de los factores para realizar operaciones importa.  

Podemos utilizar este truquito para recordar el orden en el que javaScript tratará el cálculo que le pidamos que haga:  B I D M A S 

Es un acrónimo que significa: 

B – (brackets) 

I – indices2 

D – division / 

M – multiplication * 

A – addition + 

S – substraction - 

Atajos para los números​​

JavaScript nos proporciona atajos (aka shorthand notationspara optimizar nuestro código. 

let likes = 10; likes = likes + 1; // 11 // same as likes++ // 11 let dogs = 3; // to add 2 more dogs = dogs + 3; // same as dogs += 3

Y lo mismo es aplicable para restas, divisiones y multiplicaciones. 

Objects

Arrays

Los arrays nos sirven para guardar datos de manera agrupada, algo así como una colección de datos relacionados entre sí. 

Pueden almacenar cualquier tipo de data type. 

👉 Aquí tienes una guía completa sobre los métodos más comunes de los arrays.

let friends = ['Joey', 'Monica', 'Chadler', 'Ross', 'Rachel', 'Phoebe'];

Functions

Las funciones son básicamente bloques de código reutilizable. 

Podemos clasificarlas en function declarations function expressions.

Function declaration: función declarada sin vincularla a ninguna variable.

function greet() { console.log('hola caracola'); } greet(); // 'hola caracola'

Function expression: declaramos una variable y le asignamos una función como valor.

const speak = function() { console.log('hola holita vecinita'); } speak(); // 'hola holita vecinita'

Las dos funciones se comportan igual pero hay una pequeña diferencia que tiene que ver con el hoisting.

Así, si invocamos nuestra función greet() antes de haberla declarado, se ejecutará sin problemas, porque lo que en realidad pasa es que javascript coge esa función y la eleva (hoisting) al principio del archivo. Por eso funciona.

greet(); // function declaration function greet() { console.log('hola caracola'); } // 'hola caracola'

El hoisting, sin embargo, NO FUNCIONA con las function expressions

speak(); // function expression const speak = function() { console.log('hola holita vecinita'); } // ReferenceError: Cannot access 'speak' before initialization

Dicho esto, me parece más seguro y limpio usar functions expressions en lugar de function declarations.

Uso del return

En ocasiones querremos que una función nos devuelva algún valor no necesariamente a través de la consola de chrome. Por ejemplo, si queremos calcular la edad de una persona para poder usar ese número posteriormente, de nada nos serviría hacer un console.log, porque lo queremos es usar la variable age.

const calculateAge = function(birthYear) { let currentYear = 2019; let age = currentYear - birthYear; console.log(age); }; calculateAge(1989); console.log(age); // ReferenceError: age is not defined

En este caso, la variable age no se guarda en ninguna parte más allá de la variable local dentro de la función.

Para poder guardarla, podemos usar un return, y guardar así el valor que queramos que la función nos devuelva. Así, el dato que sea estará disponible desde dentro de la función cuando lo necesitemos. 

const calculateAge = function(birthYear) { let currentYear = 2019; return currentYear - birthYear; }; const ageMonica = calculateAge(1979); console.log(ageMonica); // 40

Arrow functions

A partir de la versión ES6 de javaScript existe una manera más limpia y moderna de escribir funciones. A las funciones que toman esta forma se las llama arrow functions (aka funciones de flecha). 

Con esta característica, conseguimos que una función así: 

const calculateAge = function(birthYear) { return 2019 - birthYear; };

se pueda simplificar, en una sola línea de esta manera:

const calculateAge = birthYear => 2019 - birthYear; const ageMonica = calculateAge(1979); console.log(ageMonica); // 40

Las normas son sencillas: 

  • eliminamos la keyword function.
  • si sólo hay un parámetro, omitimos los paréntesis.
  • si no hay ningún parámetro, ponemos paréntesis vacíos.
  • añadimos una flecha después del parámetro.
  • si tenemos un único return (en una sola línea), eliminamos la keyword return y las llaves. 

Booleans

Los booleans son habitualmente utilizados en if statements, para evaluar si una condición se cumple o no y tomar ciertas decisiones en base a esa condición. 

let user = false; if(user) { console.log('user is', user); } else { console.log('ok, then user is', user); } // ok, then user is false

Ten en cuenta que la condición que pongas en el if se evalúa como true. Es decir, el ejemplo de arriba lo podríamos traducir como "si user es true", independientemente del valor que tome la variable user al inicializarla, que en este caso es false.

Métodos más comunes que devuelven booleans

método

uso

(EJEMPLOS HECHOS EN LA CONSOLA DE CHROME)

.includes(‘x’) 

Busca el que caracter (o grupo de caracteres) que le pasemos por parámetro y si lo encuentra, devuelve trueSi no, devuelve false. 

let vegetable = 'brocoli'; vegetable.includes('o'); // true
let vegetables = 'brocoli and carrot'; vegetables.includes('carrot'); // true

Symbols

Los symbols son únicos, no puede existir un symbol igual que otro.

SINTAXIS:

const symbolOne = Symbol();

🧐 Fíjate que no utilizamos la keyword "new", para crear un symbol.

Los symbols son primitive types (más información sobre eso en la sección de abajo).

const symb1 = Symbol();
const symb2 = Symbol();
console.log(symb1, symb2, typeof symb1); // Symbol() Symbol() "symbol"

Aunque parezcan idénticos, no lo son. 😮

console.log(symb1 === symb2); // false
console.log(symb1 == symb2); // false

Podemos pasarle identificadores (en inglés, indentifiers), para describirlos. Incluso dándoles el mismo indentifier, seguirían sin ser iguales.

const symb1 = Symbol('a generic name');
const symb2 = Symbol('a generic name');
console.log(symb1, symb2, typeof symb1); // Symbol(a generic name) Symbol(a generic name) "symbol"
console.log(symb1 === symb2); // false
console.log(symb1 == symb2); // false

Los symbols puede ser usados como keys o nombres de propiedades de un objeto. Vamos a verlo con un ejemplo, creando un objeto normal:

const friend = {};
friend.name = 'Chadler';
friend.job = 'business analyst';

Si ahora le damos otro valor a la propiedad job, éste se sobrescribirá, eliminando el valor business analyst y sustituyéndolo por el nuevo.

const friend = {};
friend.name = 'Chadler';
friend.job = 'business analyst';
friend.job = 'copywriter';
console.log(friend); // {name: "Chadler", job: "copywriter"}

Es decir, no podemos darle dos valores distintos a una misma propiedad. Pero sí que podríamos hacerlo utilizando symbols.

const symb1 = Symbol('a generic name');
const symb2 = Symbol('a generic name');

const friend = {};
friend.name = 'Chadler';
friend.job = 'business analyst';
friend.job = 'copywriter';

friend.symb1 = 'New York';
friend.symb2 = 'Tulsa';

console.log(friend); // {name: "Chadler", job: "copywriter", symb1: "New York", symb2: "Tulsa"}

Operadores de comparación

Es vital no confundir este signo =  con este == ni con este otro === . 

SIGNO

uso

(EJEMPLOS HECHOS EN LA CONSOLA DE CHROME)

=

Asigna un valor a una variable. 

El valor la variable fish es Dori. 

let fish = 'Dori';

==

Double equals


Compara dos valores para ver si son iguales y de serlo, devuelve true. 

 

Recuerda que javaScript es case sensitive. 

 

A esto se le conoce como abstract equality loose comparison (aka comparación flojilla 😅 ) que significa que no se tienen en cuenta los value types de las variables que estamos comparando. 

let country = 'Spain'; country == 'Germany' //false country == 'Spain' // true

!=

Es una variante del anterior. Hace lo contrario: compara dos valores para ver si son diferentes, y de serlo, devuelve true. 

let country = 'Spain'; country != 'Germany' // true country != 'Spain' // false

===

Triple equals


A este signo se le conoce como strict comparison 

 

Es más seguro y recomendable utilizar este tipo de operador de comparación, ya que también tiene en cuenta los value types a la hora de comparar. 

let age = 30; age == '30' // true let age = 30; age === '30' // false

Otros operadores comunes

SIGNO

uso

+=

Sirve para agregar contenido al ya existente, en lugar de sobreescribirlo.

let fishes = ['Nemo', 'Peet']; let fish = ' Dori'; fishes += fish; console.log(fishes) // Nemo,Peet Dori

Conversión de tipos (aka type coercion

Imagina que tienes una puntuación en un string pero la necesitas en número porque tienes que operar con ella. Para convertir un string en un número: 

let score = '85'; let threePointer = 3; score = Number(score); score + threePointer; // 88

Si queremos convertir un número en un string: 

let year = 1990; year = String(year); // "1990" // same as: year.toString(); // "1990"

Primitive types versus reference types

Es fundamental entender la diferencia entre los primitive types y los reference types. Aquí un esquemita para empezar:

Primitive types

  • numbers
  • strings
  • booleans
  • null
  • undefined
  • symbols

Reference types

  • todo tipo de objetos, por ejemplo:

    👉 object literals

    👉 arrays

    👉 functions

   👉 dates

Así que bien podríamos llamar a los reference types "object types", porque todo objeto es un reference type. La diferencia entre un tipo y otro radica en cómo se usan y guardan en la memoria. Existen dos tipos de memoria: la stack memory y la heap memory. Son dos partes distintas de la memoria destinadas a almacenar diferentes cosas.

Cuando declaramos un primitive type, javascript lo guarda en su stack memory, mientras que los reference types son almacenados en la heap memory. Los valores almacenados en la stack memory son rápidamente accesibles, pero el espacio de esta memoria es limitado. 

La memoria heap almacena tipos de datos más completos (o sea, objetos), por eso, su espacio es mayor, pero el acceso a ella es más lento. Lo que ocurre cuando almacenamos un valor en la stack memory, es que javascript asigna el nombre de la variable como un accessor (como un punto de acceso). Es decir, si tenemos una variable así:

let name = 'Max';

'name' siempre será el accessor que buscará javascript para darnos el valor de 'Max'.

Pero con los reference types no ocurre lo mismo, porque son almacenados en la heap memory y son accedidos por javascript a través de un pointer que apunta a un sitio de la memoria stack donde se guarda una referencia a dicho reference type. Podemos entender un pointer como un puente entre el valor del reference type (que es un objeto) en la memoria heap y el nombre de ese objeto en la memoria stack. Aquí un esquemita para entendernos mejor:

esquema primitive vs reference types

Primitive y reference types en la práctica

Supongamos que declaramos dos variables y asignamos el valor de la segunda a la primera. 

let billOne = 30; let billTwo = billOne;

Javascript guarda estas variables en su memoria stack y hace una copia del valor de billOne, asignándolo también a billTwo. Es decir:

30

billTwo


30

billOne


El valor es el mismo, pero javascript los almacena cada uno en un espacio, ocupando dos "sitios" en lugar de uno. Así si ahora actualizásemos el valor de billOne, billTwo no se vería afectada.

let billOne = 45; console.log(billTwo); // 30

Pero no ocurre lo mismo cuando creamos un reference type. Vamos a crearnos un objeto y asignarlo a una variable llamada clientOne:

{ name: 'Sheldon', bill: 74 }

Javascript lo almacena en la memoria heap, pero creará un pointer en la memoria stack para tener una referencia a dicho objeto. Ese pointer queda vinculado al nombre de la variable (clientOne). Es un ejemplo parecido al del esquema de arriba, pero con un object literal en lugar de con un array. 

Lo interesante viene cuando creamos otro objeto y lo asignamos al valor de userOne:

let clientOne = { name: 'Sheldon', bill: 74 }; let clientTwo = clientOne;

JavaScript no crea una copia del nuevo objeto en en la memoria heap, al contrario de lo que hacía con primitive types en la memoria stack. Lo que hace es crear otro pointer vinculado a la nueva variable (clientTwo), pero que apunta al mismo objeto en la memoria heap. Así que ambos  pointers apuntan al mismo objeto en la memoria heap. 

objetos en heap memory

Esto significa que si actualizásemos clientOne, clientTwo también obtendría el nuevo valor, porque ambos pointers están apuntando al mismo objeto en la memoria heap.

let clientOne = { name: 'Sheldon', bill: 74 }; let clientTwo = clientOne; console.log(clientOne.bill); // 74 console.log(clientTwo.bill); // 74 clientOne.bill = 100; console.log(clientOne.bill); // 100 console.log(clientTwo.bill); // 100

Visto esto, recuérdalo si en el futuro asignas a una variable el valor de otra, dependiendo de si estés creando una variable de tipo primitive o de tipo reference, porque el resultado, como hemos visto, será distinto. 🤓

¡Y hasta aquí hemos llegado! Si crees que este post puede serle útil a alguien, ¡compártelo!

Otros artículos que pueden interesarte

Días del 353 al 386
Objetivos versus realidad Y nuevamente, llegó otro día clave. Llegó…y pasó. El pasado 4 de marzo este Reto Computer Geek[...]
Proyecto MeteoApp | Parte #1
¿Qué vamos a construir? Vamos a construir a una app para buscar la predicción meteorológica en cualquier ciudad del mundo,[...]
Días del 2 al 4
"Si buscas resultados distintos no hagas siempre lo mismo" - Albert Einstein Estos días estoy aprendiendo a hacer loops en[...]

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Como toda web legal que se precie, utilizamos cookies para asegurar que damos la mejor experiencia al usuario en nuestro sitio web. Si continúas utilizando este sitio asumiremos que estás de acuerdo. más información

Los ajustes de cookies de esta web están configurados para "permitir cookies" y así ofrecerte la mejor experiencia de navegación posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estarás dando tu consentimiento a esto.

Cerrar