JavaScript
Tutorial JavaScript: Tipos de datos
JavaScript tipos de datos: definición y ejemplos. Domina los diferentes tipos de datos en JavaScript con ejemplos prácticos y detallados.
Aprende JavaScript y certifícateTipos primitivos básicos: tipado dinámico, Number, String, Boolean
En JavaScript, el tipado dinámico permite que las variables cambien de tipo durante la ejecución del programa. No es necesario especificar el tipo al declarar una variable; JavaScript determina el tipo en función del valor asignado.
El tipo Number representa tanto números enteros como de punto flotante. Se utiliza para realizar operaciones matemáticas y cálculos numéricos. Por ejemplo:
let age = 30;
let temperature = -5.5;
Las Strings son cadenas de texto que se utilizan para representar caracteres y palabras. Se pueden definir usando comillas simples ' '
, comillas dobles " "
o backticks `
para crear template literals que permiten la interpolación de variables:
let firstName = "Juan";
let greeting = `Hola, ${firstName}!`;
El tipo Boolean tiene solo dos valores posibles: true
o false
. Es fundamental para realizar evaluaciones lógicas y controlar el flujo de ejecución mediante estructuras condicionales:
let isMember = true;
let hasAccess = false;
Debido al tipado dinámico, una variable en JavaScript puede cambiar de tipo al asignarle un nuevo valor de diferente tipo primitivo:
let variable = 100; // variable es un Number
variable = "Cien"; // ahora es una String
variable = false; // ahora es un Boolean
Es crucial estar al tanto del tipo de datos con el que se está trabajando para evitar errores inesperados. La función typeof
es útil para verificar el tipo de una variable en tiempo de ejecución:
let data = 42;
console.log(typeof data); // "number"
Tipos primitivos especiales: undefined y null, Symbol, BigInt
JavaScript cuenta con varios tipos primitivos especiales que manejan situaciones únicas en el lenguaje. Estos tipos son undefined, null, Symbol y BigInt.
El valor undefined se asigna automáticamente a variables que han sido declaradas pero no inicializadas. Representa la ausencia de un valor asignado. Por ejemplo:
let user;
console.log(user); // undefined
Por otro lado, null es un valor que indica intencionalmente la ausencia de cualquier objeto o valor. Se utiliza para resetear una variable o indicar que aún no tiene un valor significativo:
let product = null;
console.log(product); // null
Aunque ambos representan una falta de valor, undefined y null tienen diferencias clave. undefined se refiere a variables que no han sido definidas o inicializadas, mientras que null es un valor asignable que indica ausencia intencional. Es importante distinguir entre ellos al realizar comparaciones:
console.log(undefined == null); // true (igualdad débil)
console.log(undefined === null); // false (igualdad estricta)
El tipo Symbol, introducido en ES6, se utiliza para crear identificadores únicos e inmutables. Los Symbols son útiles para crear propiedades privadas en objetos o evitar colisiones de nombres:
const id = Symbol('id');
let user = {
name: 'Alice',
[id]: 12345
};
En este ejemplo, la propiedad [id]
es única y no colisionará con otras propiedades. Los Symbols no son enumerables por defecto, lo que añade una capa de privacidad a las propiedades de los objetos.
El tipo BigInt permite representar números enteros de gran tamaño, más allá del límite del tipo Number (253 - 1). Es esencial cuando se trabaja con cifras muy grandes que requieren precisión:
const bigNumber = 9007199254740991n;
const anotherBigNumber = BigInt('9007199254740991500000000');
Para crear un BigInt, se añade la letra n al final del número o se utiliza la función BigInt(). Las operaciones aritméticas con BigInt son similares a las de Number, pero no se pueden mezclar tipos sin conversión explícita:
const sum = bigNumber + 10n; // Correcto
const invalidSum = bigNumber + 10; // TypeError
Es crucial entender que los BigInt y los Number no son intercambiables. Intentar combinarlos sin conversión resultará en un error de tipo. Para comparar un BigInt con un Number, es necesario asegurarse de que ambos son del mismo tipo:
const maxSafeInteger = Number.MAX_SAFE_INTEGER;
console.log(bigNumber > maxSafeInteger); // true
console.log(bigNumber === BigInt(maxSafeInteger)); // false
Al trabajar con estos tipos primitivos especiales, es fundamental ser consciente de sus características únicas para evitar errores y aprovechar al máximo las capacidades de JavaScript.
Tipos de referencia: diferencia entre tipos primitivos y tipos de referencia
En JavaScript, los tipos de referencia son esenciales para manejar datos complejos como objetos, arrays y funciones. A diferencia de los tipos primitivos, que almacenan directamente el valor asignado, los tipos de referencia almacenan una dirección en memoria que apunta al valor real.
Los tipos primitivos incluyen Number
, String
, Boolean
, undefined
, null
, Symbol
y BigInt
. Cuando asignamos un tipo primitivo a una variable, esta almacena el valor en sí mismo:
let age = 30;
let greeting = "Hello";
En este ejemplo, age
y greeting
contienen directamente los valores 30
y "Hello"
respectivamente.
Por otro lado, los tipos de referencia comprenden objetos, arrays y funciones. Al asignar un tipo de referencia a una variable, esta no almacena el valor directamente, sino una referencia al lugar en memoria donde se ubica el objeto:
let user = { name: "Alice", email: "alice@example.com" };
let numbers = [1, 2, 3, 4, 5];
Aquí, user
y numbers
almacenan referencias a sus respectivos objetos en el heap de memoria.
Una diferencia clave entre ambos tipos es cómo se comportan al asignar o copiar valores. Con los tipos primitivos, al copiar una variable a otra, se crea una copia independiente:
let x = 10;
let y = x;
y = 20;
console.log(x); // Output: 10
En este caso, x
permanece con el valor 10
, ya que y
es una copia separada.
Sin embargo, con los tipos de referencia, al copiar una variable a otra, ambas apuntan al mismo objeto:
let obj1 = { message: "Hi" };
let obj2 = obj1;
obj2.message = "Hello";
console.log(obj1.message); // Output: "Hello"
Aquí, al modificar obj2.message
, también cambiamos obj1.message
porque ambos referencian al mismo objeto en memoria.
Este comportamiento es especialmente importante al pasar variables a funciones. Con tipos primitivos, se pasa una copia del valor:
function increment(num) {
num++;
}
let count = 5;
increment(count);
console.log(count); // Output: 5
El valor de count
no cambia, ya que la función trabaja con una copia.
Con tipos de referencia, se pasa la referencia al objeto, lo que permite que la función modifique el objeto original:
function addItem(array, item) {
array.push(item);
}
let fruits = ["apple", "banana"];
addItem(fruits, "orange");
console.log(fruits); // Output: ["apple", "banana", "orange"]
En este ejemplo, la función addItem
modifica directamente el array fruits
.
Para evitar modificaciones no deseadas en objetos compartidos, es común crear copias de los mismos. Una forma de hacer una copia superficial de un objeto es usando el operador spread { ...obj }
:
let original = { a: 1, b: 2 };
let copy = { ...original };
copy.a = 3;
console.log(original.a); // Output: 1
La variable copy
es una nueva referencia que no afecta al objeto original
.
Sin embargo, las copias superficiales no son suficientes para objetos anidados. En estos casos, es necesario realizar una copia profunda utilizando métodos como structuredClone
:
let nestedObj = { a: 1, b: { c: 2 } };
let deepCopy = structuredClone(nestedObj);
deepCopy.b.c = 3;
console.log(nestedObj.b.c); // Output: 2
De esta manera, se asegura que las modificaciones en deepCopy
no afecten a nestedObj
.
Entender la diferencia entre tipos primitivos y tipos de referencia es crucial para manejar correctamente la mutabilidad y el alcance de los datos en JavaScript. Los tipos de referencia permiten una manipulación más flexible de los datos, pero requieren precaución para evitar efectos secundarios inesperados.
Operaciones y verificación de tipos
Al trabajar con diferentes tipos de datos en JavaScript, es fundamental entender cómo se comportan las operaciones entre ellos y cómo verificar el tipo de una variable en tiempo de ejecución. JavaScript es un lenguaje de tipado dinámico y realiza coerciones de tipo implícitas en ciertas operaciones, lo que puede conducir a resultados inesperados si no se maneja correctamente.
La coerción de tipos es el proceso por el cual JavaScript convierte un valor de un tipo a otro durante una operación. Por ejemplo, al sumar un Number y una String, JavaScript convierte el número a una cadena y realiza una concatenación:
let result = 5 + "10";
console.log(result); // "510"
En este caso, la variable result
es una String que contiene "510"
, ya que el número 5
se convirtió en la cadena "5"
antes de la concatenación. Es importante estar atento a estas conversiones automáticas para evitar comportamientos inesperados.
Al realizar operaciones aritméticas con operadores como -
, *
o /
, JavaScript intenta convertir las Strings a Numbers:
let difference = "20" - 5;
console.log(difference); // 15
Aquí, la cadena "20"
se convierte en el número 20
antes de realizar la resta. Sin embargo, si la cadena no puede convertirse en un número válido, el resultado será NaN
(Not-a-Number):
let invalidOperation = "hello" * 2;
console.log(invalidOperation); // NaN
El valor NaN
indica que una operación aritmética no produjo un número válido. Puedes verificar si un valor es NaN
utilizando la función isNaN()
:
console.log(isNaN(invalidOperation)); // true
Comprender la diferencia entre los operadores de igualdad ==
y ===
es crucial. El operador ==
realiza una comparación débil, que incluye coerción de tipos, mientras que ===
realiza una comparación estricta, sin coerción:
console.log(5 == "5"); // true
console.log(5 === "5"); // false
En el primer caso, JavaScript convierte la cadena "5"
al número 5
antes de comparar. En el segundo, como los tipos son diferentes (Number
y String
), la comparación estricta devuelve false
. Es una buena práctica utilizar el operador ===
para evitar resultados inesperados debidos a coerciones implícitas de tipo.
La función typeof
es útil para determinar el tipo primitivo de una variable:
let value = true;
console.log(typeof value); // "boolean"
Sin embargo, al trabajar con objetos, typeof
puede no proporcionar suficiente información. Por ejemplo, tanto los arrays como los objetos literales devuelven "object"
:
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
Para verificar si una variable es un array, se puede utilizar el método Array.isArray()
:
let list = [1, 2, 3];
console.log(Array.isArray(list)); // true
El operador instanceof
permite comprobar si un objeto es instancia de una clase o constructor específico:
function Person(name) {
this.name = name;
}
let alice = new Person("Alice");
console.log(alice instanceof Person); // true
Este operador es útil para verificar el tipo de objetos personalizados. Para obtener información más precisa sobre el tipo de un valor, se puede utilizar el método Object.prototype.toString.call()
:
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call({})); // "[object Object]"
Este método es especialmente útil para distinguir entre diferentes tipos de objetos y valores primitivos.
Para evitar las coerciones implícitas, es recomendable realizar conversiones explícitas de tipos cuando sea necesario. Por ejemplo, para convertir una String a Number:
let str = "42";
let num = Number(str);
console.log(num); // 42
console.log(typeof num); // "number"
También es posible convertir una String a Number utilizando el operador unario +
:
let num = +"42";
Para convertir un valor a String, se puede utilizar la función String()
:
let value = 100;
let str = String(value);
console.log(str); // "100"
console.log(typeof str); // "string"
La conversión a Boolean es útil para evaluar la "verdad" de un valor. Los valores que JavaScript considera falsy son: false
, 0
, ""
(cadena vacía), null
, undefined
y NaN
. Cualquier otro valor es truthy:
let value = 0;
let bool = Boolean(value);
console.log(bool); // false
Al realizar operaciones lógicas, JavaScript convierte automáticamente los valores a booleanos según estas reglas. Es esencial ser consciente de este comportamiento para evitar errores en las condiciones.
Recapitulando, para mantener un código robusto y evitar errores relacionados con los tipos de datos:
- Utiliza comparaciones estrictas (
===
y!==
) en lugar de las débiles (==
y!=
). - Realiza conversiones explícitas de tipos en lugar de confiar en las coerciones implícitas.
- Verifica los tipos de datos con
typeof
,instanceof
oArray.isArray()
según corresponda. - Ten cuidado al operar con
null
yundefined
, y recuerda quetypeof null
devuelve"object"
. - Utiliza
Number.isNaN()
para verificar si un valor esNaN
de manera fiable.
Conversiones entre tipos de datos
En JavaScript, es común la necesidad de convertir datos de un tipo a otro, ya sea para realizar operaciones específicas o para asegurar que los valores sean compatibles con ciertas funciones. Estas conversiones entre tipos de datos pueden ser explícitas o implícitas, y comprender cómo funcionan es esencial para evitar errores y comportamientos inesperados en el código.
Las conversiones implícitas, también conocidas como coerciones de tipo, ocurren automáticamente cuando JavaScript evalúa expresiones que involucran diferentes tipos de datos. Sin embargo, para tener un mayor control y claridad en el código, es recomendable realizar conversiones explícitas utilizando funciones y métodos proporcionados por el lenguaje.
Para convertir valores a números, se puede utilizar la función Number()
, que intenta transformar el valor dado en un número. Si la conversión no es posible, devuelve NaN
(Not-a-Number). Por ejemplo:
let value = "42";
let numberValue = Number(value); // 42
Otra forma de convertir cadenas a números enteros o decimales es mediante las funciones parseInt()
y parseFloat()
, respectivamente. parseInt()
analiza la cadena y devuelve un número entero, permitiendo especificar la base numérica:
let hexNumber = "0xFF";
let intValue = parseInt(hexNumber, 16); // 255
Es importante tener en cuenta que parseInt()
y parseFloat()
analizan la cadena hasta donde es posible extraer un número válido, ignorando caracteres no numéricos posteriores:
let mixedString = "123abc";
let parsedNumber = parseInt(mixedString); // 123
Para convertir valores a cadenas de texto, se utiliza la función String()
o el método toString()
. El método toString()
está disponible en muchos tipos de datos y permite especificar una base numérica cuando se trata de números:
let num = 255;
let hexString = num.toString(16); // "ff"
Al convertir valores a booleanos, la función Boolean()
es útil. Esta conversión sigue las reglas de los valores truthy y falsy en JavaScript. Los valores considerados falsy son false
, 0
, ""
(cadena vacía), null
, undefined
y NaN
. Cualquier otro valor es truthy:
let zero = 0;
let isZeroTruthy = Boolean(zero); // false
En situaciones donde es necesario convertir objetos o arrays a valores primitivos, se utilizan los métodos valueOf()
y toString()
. Por defecto, JavaScript llama a estos métodos cuando necesita convertir un objeto a un tipo primitivo en operaciones como comparaciones o concatenaciones:
let date = new Date();
let timestamp = date.valueOf(); // Número que representa el tiempo en milisegundos
Para convertir objetos a JSON, se emplea el método JSON.stringify()
, que transforma un objeto JavaScript en una cadena JSON. De manera inversa, JSON.parse()
convierte una cadena JSON en un objeto:
let user = { name: "Alice", age: 30 };
let jsonString = JSON.stringify(user); // '{"name":"Alice","age":30}'
let parsedUser = JSON.parse(jsonString); // Objeto original
Al trabajar con tipos especiales como BigInt, es necesario realizar conversiones cuidadosas. Para convertir un BigInt a Number, se puede usar el constructor Number()
, aunque hay que tener precaución, ya que puede provocar pérdida de precisión si el BigInt es demasiado grande:
let bigIntValue = 12345678901234567890n;
let numberValue = Number(bigIntValue); // Pérdida de precisión
En el caso de los Symbols, su conversión a otros tipos es limitada. Los Symbols no pueden convertirse automáticamente a cadenas de texto, y hacerlo puede generar errores. Si es necesario, se puede obtener su descripción:
let sym = Symbol("id");
let symDescription = sym.description; // "id"
Es recomendable evitar mezclas innecesarias de tipos y realizar conversiones explícitas cuando sea necesario. Esto mejora la legibilidad y confiabilidad del código, y previene comportamientos inesperados debido a las coerciones implícitas.
Ejercicios de esta lección Tipos de datos
Evalúa tus conocimientos de esta lección Tipos de datos con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Funciones flecha
Polimorfismo
Array
Transformación con map()
Gestor de tareas con JavaScript
Manipulación DOM
Funciones
Funciones flecha
Async / Await
Creación y uso de variables
Excepciones
Promises
Funciones cierre (closure)
Herencia
Herencia
Estructuras de control
Selección de elementos DOM
Modificación de elementos DOM
Filtrado con filter() y find()
Funciones cierre (closure)
Funciones
Mapas con Map
Reducción con reduce()
Callbacks
Manipulación DOM
Promises
Async / Await
Eventos del DOM
Introducción a JavaScript
Async / Await
Promises
Filtrado con filter() y find()
Callbacks
Creación de clases y objetos Restaurante
Reducción con reduce()
Filtrado con filter() y find()
Reducción con reduce()
Conjuntos con Set
Herencia de clases
Eventos del DOM
Clases y objetos
Modificación de elementos DOM
Mapas con Map
Introducción a JavaScript
Funciones
Tipos de datos
Clases y objetos
Array
Conjuntos con Set
Array
Encapsulación
Clases y objetos
Uso de operadores
Uso de operadores
Estructuras de control
Excepciones
Transformación con map()
Funciones flecha
Selección de elementos DOM
Encapsulación
Mapas con Map
Creación y uso de variables
Polimorfismo
Tipos de datos
Estructuras de control
Todas las lecciones de JavaScript
Accede a todas las lecciones de JavaScript y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Javascript
Introducción Y Entorno
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Funciones Cierre (Closure)
Sintaxis
Arrays Y Métodos
Estructuras De Datos
Conjuntos Con Set
Estructuras De Datos
Mapas Con Map
Estructuras De Datos
Funciones Flecha
Programación Funcional
Filtrado Con Filter() Y Find()
Programación Funcional
Transformación Con Map()
Programación Funcional
Reducción Con Reduce()
Programación Funcional
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Manipulación Dom
Dom
Selección De Elementos Dom
Dom
Modificación De Elementos Dom
Dom
Eventos Del Dom
Dom
Callbacks
Programación Asíncrona
Promises
Programación Asíncrona
Async / Await
Programación Asíncrona
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender los tipos de datos primitivos y de objeto en JavaScript.
- Aprender a declarar y utilizar variables para almacenar diferentes tipos de datos.
- Familiarizarse con la creación y manipulación de objetos y arrays.
- Conocer cómo utilizar funciones y métodos para operar con diferentes tipos de datos.
- Entender el propósito y uso de los tipos de datos especiales
undefined
,null
ySymbol
.