Tipos de datos en JavaScript: ¿Cuáles son los mas comunes?
Los tipos de datos en JavaScript definen la naturaleza de la información que puedes manipular en tu código. ¿Cuáles son y para qué sirven? En este artículo, exploraremos qué son los tipos primitivos y de referencia, cómo se utilizan y te mostraremos ejemplos prácticos para comprender mejor su funcionamiento.

Índice
1. ¿Cuáles son los tipos de datos en JavaScript?
Primero vamos a responder ¿Qué son los tipos de datos?. En JavaScript, los tipos de datos son como las diferentes categorías en las que podemos clasificar la información que manejamos. Cada tipo de dato tiene características y comportamientos específicos, lo que determina cómo podemos utilizarlo en nuestros programas.
💡RECUERDA! Estos tipos de datos, se guardan principalmente en variables de JavaScript para sus posterior manipulación y uso en diferentes partes del programa!
Los mismos se pueden dividir en dos grandes categorías:
- Tipos de datos primitivos.
- Tipos de datos de referencia.
1.1. Tipos de datos primitivos:
Los tipos de datos primitivos son los más básicos y representan valores individuales.
A continuación dejamos un resumen de los mas importantes y luego ampliamos:
Number: Representa números tanto enteros como de punto flotante.String: Representa cadenas de texto. Se escriben entre comillas simples o dobles.Boolean: Representa valores lógicos: verdadero (true) o falso (false).Null: Representa la ausencia intencional de cualquier valor.Undefined: Representa una variable que ha sido declarada pero aún no ha sido asignada.Symbol: Representa un valor único e inmutable, a menudo utilizado para crear propiedades de objetos únicas.BigInt: Representa números enteros de precisión arbitraria, utilizados para manejar números muy grandes.
CARACTERÍSTICAS principales de los tipos de datos primitivos:
- Valores individuales:
- Representan un único valor.
- Inmutables:
- Una vez asignados a una variable, su valor no puede ser cambiado directamente.
- Almacenamiento:
- Se almacenan directamente en la memoria stack.
- Comparación:
- Se compara el valor en sí.
1.1.1. Number:
En JavaScript, el tipo de dato Number se utiliza para representar valores numéricos, tanto enteros como de punto flotante. Esto incluye números positivos, negativos, cero, y algunos valores especiales como Infinity, -Infinity y NaN.
Características principales de Number:
- Representación interna: Los números en JavaScript se almacenan en formato binario de 64 bits de doble precisión IEEE 754. Esto significa que hay un rango limitado de valores que se pueden representar con precisión.
- Valores especiales:
- Infinity: Representa el infinito positivo.
- -Infinity: Representa el infinito negativo.
- NaN: (Not a Number) Indica un resultado de una operación matemática que no es un número válido, como dividir por cero.
- Operaciones comunes: Se pueden realizar diversas operaciones matemáticas con números, como suma, resta, multiplicación, división, módulo, etc.
- Conversión: Los números se pueden convertir a otros tipos de datos, como cadenas (strings) utilizando el método
toString().
Ejemplo de variables usando tipo de dato number:
let edad = 30; // Número entero
let pi = 3.14159; // Número de punto flotante
let resultado = 10 / 0; // Infinity
let error = "Hola" * 2; // NaN
console.log(edad);
console.log(pi);
console.log(resultado);
console.log(error);Lenguaje del código: JavaScript (javascript)
¿Cuándo usar Number?
- Cálculos matemáticos: Para realizar cualquier tipo de operación numérica.
- Comparaciones: Para comparar valores numéricos utilizando operadores como
>,<,===,!==, etc. - Indices de arrays: Para acceder a elementos específicos de un array.
- Propiedades numéricas de objetos: Para definir propiedades numéricas en objetos.
Consideraciones importantes con Number:
- Precisión: Debido a la representación interna en punto flotante, algunos números pueden tener una pequeña pérdida de precisión.
- Rango: Existe un rango máximo y mínimo para los números en JavaScript. Si se intenta representar un número fuera de ese rango, se obtendrá
Infinityo-Infinity. - NaN: Es importante verificar si el resultado de una operación es
NaNantes de realizar otras operaciones con él.
RECUERDA: El tipo de dato Number es fundamental en JavaScript para realizar cualquier tipo de cálculo o manipulación de valores numéricos. Comprender sus características y limitaciones es esencial para escribir código JavaScript sólido y eficiente.
1.1.2. String:
En JavaScript, un String (cadena de caracteres) es una secuencia de caracteres, que pueden ser letras, números, símbolos o espacios en blanco. Se utilizan para representar texto y son encerrados entre comillas simples (‘) o dobles («).
Ejemplo de variable usando string:
let saludo = "Hola, mundo!";
let nombre = 'Juan';
let vacia = ""; // Cadena vacíaLenguaje del código: JavaScript (javascript)
Características de los Strings
- Inmutabilidad: Una vez creada una cadena, no puedes modificar directamente sus caracteres individuales. Si necesitas cambiar una cadena, tendrás que crear una nueva.
- Indexación: Cada carácter en una cadena tiene un índice, empezando desde 0. Esto permite acceder a caracteres individuales o subcadenas.
- Propiedades y métodos: Los strings tienen muchas propiedades y métodos útiles para manipular texto, como
length(longitud),toUpperCase(),toLowerCase(),substring(),indexOf(), entre otros.
Operaciones comunes con Strings:
- Concatenación: Unir dos o más cadenas usando el operador
+. Ejemplo:let primerNombre = "Juan";let apellido = "Pérez";let nombreCompleto = primerNombre + " " + apellido;
- Acceso a caracteres: Utilizar corchetes para acceder a un carácter específico por su índice. Ejemplo:
let palabra = "manzana";let primeraLetra = palabra[0]; // "m"
- Métodos útiles:
length: Devuelve la longitud de la cadena.toUpperCase(): Convierte todos los caracteres a mayúsculas.toLowerCase(): Convierte todos los caracteres a minúsculas.substring(): Extrae una subcadena.indexOf(): Devuelve el índice de la primera aparición de un substring.replace(): Reemplaza una subcadena por otra.split(): Divide una cadena en un array de substrings.
Ejemplos adicionales:
let frase = "El rápido zorro marrón salta sobre el perro perezoso.";
let palabraBuscada = "zorro";
// Buscar la posición de la palabra "zorro"
let posicion = frase.indexOf(palabraBuscada);
// Convertir la frase a mayúsculas
let fraseMayuscula = frase.toUpperCase();
// Extraer la primera palabra
let primeraPalabra = frase.substring(0, frase.indexOf(" "));Lenguaje del código: JavaScript (javascript)
¿Por qué son importantes los Strings?
Los Strings son fundamentales en cualquier lenguaje de programación, ya que se utilizan para:
- Almacenar texto: Nombres, direcciones, mensajes, etc.
- Crear interfaces de usuario: Etiquetas, botones, mensajes de error, etc.
- Manipular datos: Parsear archivos, validar entradas, etc.
- Comunicación: Transmitir información a través de redes.
RECURDA: Los Strings son un tipo de dato esencial en JavaScript que nos permiten trabajar con texto de manera flexible y eficiente. Al comprender sus características y métodos, podrás crear aplicaciones más dinámicas y versátiles.
1.1.3. Boolean:
Un Boolean en JavaScript es un tipo de dato primitivo que representa uno de dos valores posibles: true o false. Esencialmente, representa una entidad lógica.
Usos comunes de Boolean:
- Condicionales: Se utilizan ampliamente en estructuras de control como
if,else,while,forpara tomar decisiones basadas en condiciones. - Operadores lógicos: Se combinan con operadores lógicos (AND, OR, NOT) para crear expresiones booleanas más complejas.
- Funciones de retorno: Las funciones pueden devolver valores booleanos para indicar éxito, fracaso o cualquier otra condición.
- Comparaciones: Se generan a partir de comparaciones entre valores (igualdad, desigualdad, mayor que, menor que, etc.).
EJEMPLOS:
let esVerdadero = true;
let esFalso = false;
if (esVerdadero) {
console.log("La condición es verdadera");
} else {
console.log("La condición es falsa");
}
let resultado = 5 > 3; // Resultado es trueLenguaje del código: JavaScript (javascript)
Explicación de este ejemplo:
- Declaración de variables booleanas:
let esVerdadero = true;: Aquí estás declarando una variable llamadaesVerdaderoy le estás asignando el valortrue. Este es un tipo de dato primitivoboolean.let esFalso = false;: Aquí estás declarando otra variable llamadaesFalsocon el valorfalse, que también es un tipo de dato primitivoboolean.
- Condicional
if-else:- La estructura
if (esVerdadero) {...} else {...}evalúa la condición que está dentro de los paréntesis. - En este caso,
esVerdaderotiene el valortrue, por lo que el bloque de código dentro delifse ejecutará, imprimiendo"La condición es verdadera". - Si
esVerdaderohubiese sidofalse, se habría ejecutado el bloqueelse, y habría imprimido"La condición es falsa".
- La estructura
- Evaluación de una expresión booleana:
let resultado = 5 > 3;: Aquí, estás evaluando una expresión que compara dos números (5y3).- La comparación
5 > 3evalúa si 5 es mayor que 3, lo cual es verdadero. Por lo tanto,resultadose le asigna el valortrue. - Este es un ejemplo de cómo se utilizan los valores booleanos para evaluar condiciones en JavaScript.
RECUERDA: Los valores booleanos son fundamentales en la lógica de programación y se utilizan para controlar el flujo de ejecución de un programa. Comprender cómo funcionan y cómo se utilizan es esencial para escribir código eficiente y legible.
1.1.4. Null:
En JavaScript, null es un valor primitivo que representa la ausencia intencional de cualquier otro valor. Es decir, cuando asignamos null a una variable, estamos indicando explícitamente que esa variable no tiene un valor asignado en este momento.
IMPORTANTE!!! null no es lo mismo que undefined, aunque ambos representan la ausencia de un valor. Veremos la diferencia más adelante.
¿Cuándo se utiliza null?
- Inicialización de variables: A menudo se utiliza para inicializar una variable antes de asignarle un valor real.
- Retorno de funciones: Cuando una función no encuentra un valor válido, puede devolver
nullpara indicar que no hay resultado. - Comprobación de existencia: Se utiliza para verificar si una propiedad de un objeto existe.
- Representación de valores desconocidos: En algunos casos,
nullpuede representar un valor que aún no se conoce o que puede cambiar en el futuro.
EJEMPLO:
let miVariable = null;
console.log(miVariable); // Imprime: null
function encontrarUsuario(id) {
// Simula una búsqueda en una base de datos
let usuario = null;
// ... lógica para buscar al usuario
return usuario;
}
let usuarioEncontrado = encontrarUsuario(123);
if (usuarioEncontrado === null) {
console.log("Usuario no encontrado");
}Lenguaje del código: JavaScript (javascript)
Explicación del ejemplo:
- Declaración de
miVariable:let miVariable = null;: Aquí, estás declarando una variable llamadamiVariabley asignándole el valornull. Esto indica quemiVariableexiste, pero no contiene ningún valor significativo por el momento.console.log(miVariable); // Imprime: null: Cuando imprimesmiVariableen la consola, obtienesnull, ya que eso es lo que has asignado.
- Función
encontrarUsuario:- La función
encontrarUsuariosimula la búsqueda de un usuario en una base de datos usando unid. let usuario = null;: Al comienzo de la función, la variableusuariose inicializa ennullpara indicar que, inicialmente, no se ha encontrado ningún usuario.return usuario;: La función retorna la variableusuario. Si no se encuentra al usuario,usuarioseguirá siendonull.
- La función
- Uso de
nullpara control de flujo:let usuarioEncontrado = encontrarUsuario(123);: Se llama a la funciónencontrarUsuariocon unid(en este caso,123). Dado que la lógica de búsqueda no se ha implementado, la función devuelvenull.if (usuarioEncontrado === null) {...}: Este condicional verifica siusuarioEncontradoesnull.- Como
usuarioEncontradoesnull, se ejecuta el bloque de código dentro delif, imprimiendo"Usuario no encontrado"en la consola.
Diferencia entre null y undefined:
- null: Representa la ausencia intencional de un valor. Es un valor asignado por el programador.
- undefined: Representa la ausencia de un valor asignado. Ocurre cuando una variable se declara pero no se inicializa, o cuando se intenta acceder a una propiedad que no existe.
let miVariable; // undefined (no se ha asignado ningún valor)
let otraVariable = null; // null (se ha asignado explícitamente el valor null)Lenguaje del código: JavaScript (javascript)
Comprobando si un valor es null:
Para verificar si una variable es null, se utiliza el operador de igualdad estricta (===).
if (miVariable === null) {
// El valor es null
}Lenguaje del código: JavaScript (javascript)
RECUERDA:
nulles un valor primitivo que representa la ausencia intencional de un valor.- Se utiliza para inicializar variables, indicar falta de resultados en funciones y comprobar existencia de propiedades.
- No es lo mismo que
undefined. - Se verifica con el operador
===.
1.1.5. Undefined:
Undefined es un valor primitivo en JavaScript que indica que una variable ha sido declarada pero aún no se le ha asignado ningún valor. También se devuelve cuando se intenta acceder a una propiedad de un objeto que no existe.
Casos comunes de undefined:
- Variable declarada sin asignación:
let miVariable;
console.log(miVariable); // Output: undefinedLenguaje del código: JavaScript (javascript)
- Acceso a propiedad inexistente:
let objeto = {};
console.log(objeto.propiedadInexistente); // Output: undefinedLenguaje del código: JavaScript (javascript)
Diferencia entre null y undefined
Aunque ambos representan la ausencia de un valor, hay una diferencia clave:
- null es un valor asignado intencionalmente por el programador para indicar la ausencia de un valor.
- undefined es un valor asignado automáticamente por JavaScript cuando una variable no tiene valor.
Comprobando si un valor es undefined
Para verificar si una variable es undefined, se utiliza el operador de igualdad estricta (===).
if (miVariable === undefined) {
// La variable es undefined
}Lenguaje del código: JavaScript (javascript)
RECUERDA:
undefinedes un valor primitivo que indica la ausencia de un valor asignado.- Ocurre cuando una variable se declara sin asignación, se accede a una propiedad inexistente o una función no devuelve un valor.
- No es lo mismo que
null. - Se verifica con el operador
===.
1.1.5. Symbol:
Un Symbol es un tipo de dato primitivo en JavaScript introducido en ECMAScript 6. Representa un valor único e inmutable que puede ser utilizado como identificador o clave en objetos.
Características principales de Symbol:
- Unicidad: Cada llamada a la función
Symbol()crea un nuevo símbolo único. - Inmutabilidad: Una vez creado, el valor de un símbolo no puede cambiar.
- Descripción opcional: Puedes proporcionar una descripción opcional al crear un símbolo, pero esta descripción no afecta a la unicidad del símbolo.
- Uso como clave de objeto: Los símbolos pueden ser utilizados como claves en objetos, lo que permite crear propiedades privadas o evitar conflictos de nombres.
Creación de símbolos de Symbol:
let id = Symbol(); // Crea un símbolo único
let otroId = Symbol("identificador"); // Crea un símbolo con descripciónLenguaje del código: JavaScript (javascript)
Uso de símbolos como claves de objeto:
let user = {
name: "John Doe",
[id]: 123 // Usando el símbolo como clave
};Lenguaje del código: JavaScript (javascript)
Métodos estáticos de Symbol:
- Symbol.for(key): Busca un símbolo existente en el registro global de símbolos con la clave dada. Si no existe, crea uno nuevo y lo registra.
- Symbol.keyFor(sym): Devuelve la clave asociada a un símbolo en el registro global de símbolos.
Usos comunes de símbolos:
- Creación de propiedades privadas: Los símbolos pueden ser utilizados para crear propiedades de objetos que no sean accesibles desde fuera del objeto.
- Evitar conflictos de nombres: Los símbolos pueden ser utilizados como nombres de propiedades para evitar conflictos con propiedades existentes.
- Identificación única de objetos: Los símbolos pueden ser utilizados para crear identificadores únicos para objetos.
EJEMPLO:
const privateData = Symbol('private');
class MyClass {
constructor(data) {
this[privateData] = data;
}
get data() {
return this[privateData];
}
}
let obj = new MyClass('secret data');
console.log(obj.data); // Output: 'secret data'
console.log(obj[privateData]); // Error: Cannot access private propertyLenguaje del código: JavaScript (javascript)
Explicación:
- Creación de un
Symbol:const privateData = Symbol('private');: Aquí, se crea unSymbolllamadoprivateDatacon una descripción opcional'private'. CadaSymboles único, incluso si tienen la misma descripción.- Este
Symbolserá usado como clave para una propiedad del objeto, y su principal ventaja es que no puede ser accedido ni colisionado con otras propiedades que usenstringonumbercomo clave.
- Definición de la clase
MyClass:- En la clase
MyClass, el constructor toma un parámetrodatay lo asigna a una propiedad del objeto usando elSymbolcomo clave:this[privateData] = data;. - Esto significa que
dataestá almacenada en una propiedad que no puede ser accedida de manera directa a través de una clave de tipostringonumber.
- En la clase
- Acceso al dato encapsulado:
get data() { return this[privateData]; }: Este es un accesor (getter) que permite acceder al valor almacenado en la propiedadthis[privateData]de manera controlada.- Cuando llamas a
obj.data, estegetterretorna el valor asociado alSymbolprivateData.
- Creación de una instancia y acceso a las propiedades:
let obj = new MyClass('secret data');: Se crea una instancia deMyClassy se pasa'secret data'como argumento al constructor, lo que hace quethis[privateData]en esa instancia contenga'secret data'.console.log(obj.data); // Output: 'secret data': Aquí se usa elgetterpara acceder a los datos encapsulados, y devuelve'secret data'.console.log(obj[privateData]); // Error: Cannot access private property: Este intento de acceder directamente a la propiedad usando elSymbolcomo clave provoca un error o resulta enundefined, dependiendo del entorno, porque la propiedad es efectivamente privada debido a la naturaleza única y no enumerable delSymbol.
RECUERDA: Los símbolos son una herramienta poderosa en JavaScript para crear valores únicos e inmutables. Son especialmente útiles para crear propiedades privadas y evitar conflictos de nombres.
1.1.5. BigInt:
BigInt es un tipo de dato numérico en JavaScript diseñado para manejar números enteros extremadamente grandes que superan el límite de precisión del tipo Number estándar. Esto es especialmente útil para operaciones que involucran números muy grandes, como cálculos criptográficos o análisis de datos a gran escala.
Creación de BigInt
Hay dos formas principales de crear un BigInt:
- Añadiendo
nal final de un número entero:bigIntValue = 123456789012345678901234567890n;
- Utilizando la función
BigInt():bigIntValue = BigInt("9007199254740992"); // Convertir una cadena a BigInt
Operaciones con BigInt
La mayoría de los operadores aritméticos funcionan con BigInt, pero es importante tener en cuenta que los BigInt no pueden ser mezclados con números normales.
let bigInt1 = 123n;
let bigInt2 = 456n;
let suma = bigInt1 + bigInt2; // 579n
let resta = bigInt1 - bigInt2; // -333n
let multiplicacion = bigInt1 * bigInt2; // 56088n
let division = bigInt1 / bigInt2; // 0n (división entera)
let modulo = bigInt1 % bigInt2; // 123nLenguaje del código: JavaScript (javascript)
Limitaciones y consideraciones de BigInt:
- Solo números enteros: BigInt solo puede representar números enteros, no números de punto flotante.
- No mezclable con números normales: Las operaciones entre BigInt y números normales resultarán en errores.
- Rendimiento: Las operaciones con BigInt pueden ser ligeramente más lentas que con números normales.
- Soporte: El soporte para BigInt puede variar entre navegadores.
Casos de uso
- Criptografía: Manejo de números extremadamente grandes para algoritmos criptográficos.
- Cálculos científicos: Operaciones con números muy grandes en cálculos científicos.
- Procesamiento de datos: Manipulación de grandes conjuntos de datos con números enteros.
RECUERDA: BigInt es una herramienta valiosa para trabajar con números enteros muy grandes en JavaScript. Al comprender sus características y limitaciones, puedes utilizarlos de manera efectiva en tus aplicaciones.
1.2. Tipos de datos de referencia:
Los tipos de datos no primitivos (o de referencia) son más complejos y pueden contener múltiples valores o propiedades. Son mutables, lo que significa que sus propiedades pueden ser modificadas después de su creación.
Ejemplos de objetos:
Objetos: Es una colección de propiedades, donde cada propiedad es una asociación entre un nombre (o clave) y un valor.Arrays: Colecciones ordenadas de elementos.Funciones: Bloques de código reutilizables que realizan tareas específicas.RegExp: Patrón de búsqueda que se utiliza para encontrar coincidencias en cadenas de texto.Fechas: Representan puntos específicos en el tiempo.
CARACTERÍSTICAS principales de los tipos de datos de referencia:
- Colecciones de datos:
- Pueden contener múltiples valores o propiedades.
- Mutables:
- Sus propiedades pueden ser modificadas después de su creación.
- Referencia:
- Se almacenan en el montón de memoria y se accede a ellos a través de una referencia.
- Comparación:
- Se compara la referencia, no el valor en sí.
1.2.1. Objetos:
Cuando hablamos de objetos en JavaScript como tipos de dato de referencia, estamos diciendo que una variable que almacena un objeto en realidad NO CONTIENE el objeto en sí, sino una REFERENCIA a la ubicación de ese objeto en la memoria.
Esto implica:
- Copia por referencia: Al asignar un objeto a otra variable, lo que se copia es la referencia, no el objeto en sí. Ambas variables apuntarán al mismo objeto en memoria.
- Modificaciones compartidas: Cualquier cambio realizado en el objeto a través de una variable se reflejará en todas las demás variables que hacen referencia a ese mismo objeto.
Ejemplo:
let persona1 = { nombre: "Juan", edad: 30 };
let persona2 = persona1;
persona2.edad = 31;
console.log(persona1.edad); // Imprime 31, ya que persona1 y persona2 apuntan al mismo objetoLenguaje del código: JavaScript (javascript)
Explicación del ejemplo:
- Creación del objeto
persona1:let persona1 = { nombre: "Juan", edad: 30 };: Aquí se crea un objeto con dos propiedades:nombreyedad.- Este objeto es almacenado en la memoria heap, y la variable
persona1contiene una referencia a la ubicación en la memoria donde está almacenado ese objeto.
- Asignación de la referencia a
persona2:let persona2 = persona1;: En lugar de copiar el contenido del objeto, lo que sucede aquí es quepersona2recibe la misma referencia quepersona1.- Ambos,
persona1ypersona2, ahora apuntan al mismo objeto en la memoria.
- Modificación a través de
persona2:persona2.edad = 31;: Aquí se está modificando la propiedadedaddel objeto a través de la variablepersona2.- Como
persona2ypersona1apuntan al mismo objeto en la memoria, este cambio afecta a ese único objeto, por lo que la propiedadedadse actualiza a31.
- Acceso a través de
persona1:console.log(persona1.edad); // Imprime 31: Cuando accedes a la propiedadedada través depersona1, se muestra el valor actualizado, que es31, porquepersona1ypersona2están referenciando el mismo objeto.
¿Por qué es importante entender esto?
- Evitar errores comunes: Comprender el comportamiento de los objetos por referencia es crucial para evitar errores inesperados, especialmente cuando se trabaja con objetos anidados o se pasan objetos como argumentos a funciones.
- Optimización de memoria: Al entender cómo se manejan las referencias, puedes optimizar el uso de memoria en tus aplicaciones.
- Manejo de datos complejos: Los objetos son fundamentales para modelar datos complejos en JavaScript, y comprender su comportamiento por referencia es esencial para trabajar con ellos de manera efectiva.
¿Cuándo utilizar objetos?
- Modelar entidades reales: Personas, productos, etc.
- Agrupar datos relacionados: Propiedades de un elemento HTML, configuración de una aplicación.
- Crear estructuras de datos: Arrays, listas enlazadas, árboles.
- Implementar herencia y polimorfismo: A través de prototipos.
RECUERDA:
- Los objetos en JavaScript son tipos de dato de referencia.
- Al asignar un objeto a otra variable, se copia la referencia, no el objeto en sí.
- Las modificaciones realizadas a un objeto se reflejan en todas las variables que hacen referencia a él.
- Comprender el comportamiento de los objetos por referencia es fundamental para escribir código JavaScript correcto y eficiente.
1.2.2. Arrays:
Al igual que los objetos, los arrays en JavaScript son tipos de datos de referencia. Esto significa que cuando asignamos un array a una variable, lo que realmente estamos almacenando es una REFERENCIA a la ubicación de ese array en la memoria.
Consecuencias de esto:
- Copia por referencia: Si asignamos un array a otra variable, ambas variables apuntarán al mismo array en memoria. Cualquier cambio realizado en el array a través de una variable se reflejará en la otra.
- Modificaciones compartidas: Si modificamos un elemento de un array, ese cambio se verá reflejado en todas las variables que hacen referencia a ese array.
Ejemplo:
let numeros1 = [1, 2, 3];
let numeros2 = numeros1;
// Modificamos un elemento del array
numeros2[0] = 10;
console.log(numeros1); // Imprime [10, 2, 3]
console.log(numeros2); // Imprime [10, 2, 3]Lenguaje del código: JavaScript (javascript)
Explicación del ejemplo:
- Creación del array
numeros1:let numeros1 = [1, 2, 3];: Aquí se crea un array con tres elementos[1, 2, 3].- Este array es almacenado en la memoria heap, y la variable
numeros1contiene una referencia a la ubicación en la memoria donde está almacenado ese array.
- Asignación de la referencia a
numeros2:let numeros2 = numeros1;: En lugar de copiar los valores del array, lo que sucede es quenumeros2recibe la misma referencia quenumeros1.- Ahora, tanto
numeros1comonumeros2apuntan al mismo array en la memoria.
- Modificación a través de
numeros2:numeros2[0] = 10;: Aquí se está modificando el primer elemento del array a través de la variablenumeros2.- Como
numeros2ynumeros1apuntan al mismo array en la memoria, este cambio afecta a ese único array, por lo que el primer elemento del array se actualiza a10.
- Acceso a través de
numeros1ynumeros2:console.log(numeros1); // Imprime [10, 2, 3]: Cuando accedes al array a través denumeros1, ves el array modificado, ya que tantonumeros1comonumeros2están referenciando el mismo array.console.log(numeros2); // Imprime [10, 2, 3]: Al acceder a través denumeros2, también ves el array modificado, ya que ambos apuntan al mismo array en la memoria.
¿Por qué es importante entender esto?
- Evitar errores comunes: Al comprender que los arrays se pasan por referencia, puedes evitar modificar accidentalmente datos que no querías cambiar.
- Optimizar el código: Saber cómo se manejan los arrays te permite escribir código más eficiente y evitar duplicar datos innecesariamente.
- Trabajar con estructuras de datos: Los arrays son fundamentales para crear estructuras de datos más complejas, como matrices, pilas y colas.
¿Cómo crear una copia independiente de un array?
Si deseas crear una copia independiente de un array, es decir, un nuevo array con los mismos elementos pero que no esté vinculado al original, puedes utilizar los siguientes métodos:
- Spread operator:
copiaNumeros = [...numeros1];
- Método
slice():copiaNumeros = numeros1.slice();
- Método
concat():copiaNumeros = numeros1.concat();
Ejemplo de copia independiente:
let numeros1 = [1, 2, 3];
let copiaNumeros = [...numeros1];
copiaNumeros[0] = 100;
console.log(numeros1); // Imprime [1, 2, 3]
console.log(copiaNumeros); // Imprime [100, 2, 3]Lenguaje del código: JavaScript (javascript)
RECUERDA: Los arrays en JavaScript son tipos de datos de referencia, lo que significa que las variables almacenan referencias a la ubicación en memoria del array. Comprender este concepto es fundamental para trabajar de manera efectiva con arrays y evitar errores comunes.
1.2.3. Funciones:
Entender por qué las funciones en JS se consideran datos de referencia, es fundamental para comprender su comportamiento y aprovechar al máximo sus capacidades.
¿Por qué las funciones son datos de referencia?
- Objetos de primera clase:
- En JavaScript, las funciones son objetos. Esto significa que tienen propiedades y métodos como cualquier otro objeto. Al ser objetos, son almacenados en la memoria y a las variables se les asigna una referencia a esa ubicación de memoria.
- Asignación por referencia:
- Cuando asignamos una función a una variable, lo que estamos haciendo es crear una referencia a esa función en la memoria. Si luego asignamos esa misma variable a otra, ambas variables estarán apuntando al mismo objeto función.
- Pasaje por referencia:
- Cuando pasamos una función como argumento a otra función, lo que se pasa es la referencia a esa función. Esto significa que la función interna puede modificar la función externa si tiene acceso a ella.
Ejemplo de función como dato de referencia:
function saludar() {
console.log("Hola!");
}
let saludo1 = saludar; // Asignar la referencia de la función a otra variable
let saludo2 = saludo1; // Asignar la misma referencia a otra variable
saludo1(); // Imprime: "Hola!"
saludo2(); // Imprime: "Hola!"
// Modificar la referencia en saludo1
saludo1 = function() {
console.log("Hola, cómo estás?");
};
saludo1(); // Imprime: "Hola, cómo estás?"
saludo2(); // Imprime: "Hola!" (sigue apuntando a la función original)Lenguaje del código: JavaScript (javascript)
Explicación del ejemplo:
- Definición de la función
saludar:function saludar() { console.log("Hola!"); }: Aquí se define una función llamadasaludarque, cuando se invoca, imprime «Hola!» en la consola.- La función se almacena en la memoria heap, y la variable
saludarcontiene una referencia a esa función en la memoria.
- Asignación de la referencia de la función a otras variables:
let saludo1 = saludar;: Se asigna la referencia de la funciónsaludara la variablesaludo1. Ahora,saludo1ysaludarapuntan a la misma función en la memoria.let saludo2 = saludo1;: Se asigna la misma referencia de la función (ahora contenida ensaludo1) a la variablesaludo2. Ahora,saludar,saludo1, ysaludo2apuntan a la misma función.
- Invocación de la función a través de diferentes variables:
saludo1(); // Imprime: "Hola!": Invocar la función a través desaludo1ejecuta la función original, imprimiendo «Hola!» en la consola.saludo2(); // Imprime: "Hola!": Lo mismo ocurre consaludo2, ya que ambas variables apuntan a la misma función.
- Modificación de la referencia de la función:
saludo1 = function() { console.log("Hola, cómo estás?"); };: Aquí se asigna una nueva función anónima a la variablesaludo1. Esto significa quesaludo1ya no apunta a la función originalsaludar, sino a esta nueva función.saludo1(); // Imprime: "Hola, cómo estás?": Invocarsaludo1ahora ejecuta la nueva función.saludo2(); // Imprime: "Hola!": Sin embargo,saludo2sigue apuntando a la función originalsaludar, por lo que aún imprime «Hola!».
RECUERDA: Al comprender que las funciones son datos de referencia, podemos aprovechar al máximo sus capacidades y escribir código más elegante y eficiente. Podemos crear funciones dinámicas, reutilizables y compuestas, lo que es fundamental para la programación funcional y orientada a objetos en JavaScript.
1.2.4. RegExp:
Una expresión regular (RegExp) es un patrón de búsqueda que se utiliza para encontrar coincidencias en cadenas de texto. En JavaScript, las expresiones regulares son objetos, y como tales, son datos de referencia. Esto significa que cuando asignamos una expresión regular a una variable, estamos almacenando una referencia a esa expresión en la memoria.
¿Por qué son importantes las RegExp como datos de referencia?
- Asignación por referencia: Al igual que con otros objetos, si asignamos una expresión regular a múltiples variables, todas esas variables estarán apuntando al mismo objeto en memoria. Cualquier cambio realizado en una de ellas se verá reflejado en las demás.
- Modificación de patrones: Las propiedades de un objeto RegExp pueden ser modificadas después de su creación. Por ejemplo, podemos cambiar el indicador global (g) para realizar búsquedas en toda la cadena.
- Pasaje como argumento: Las expresiones regulares pueden ser pasadas como argumentos a funciones que trabajan con patrones de búsqueda, como
match(),replace(),search(), etc.
EJEMPLO:
let patron = /hola/gi; // Busca la palabra "hola" de forma global e insensible a mayúsculas y minúsculas
let otraVariable = patron;
// Modificamos el patrón
patron.ignoreCase = false;
console.log(otraVariable.test("HOLA")); // Imprimirá false, ya que ignoreCase se ha cambiadoLenguaje del código: JavaScript (javascript)
Explicación del ejemplo:
- Creación del objeto RegExp
patron:let patron = /hola/gi;: Aquí se crea una expresión regular que busca la palabra «hola». Las opcionesg(global) yi(insensible a mayúsculas y minúsculas) especifican cómo se debe realizar la búsqueda.- Este objeto RegExp se almacena en la memoria heap, y la variable
patroncontiene una referencia a la ubicación en la memoria donde está almacenado ese objeto.
- Asignación de la referencia del objeto RegExp a otra variable:
let otraVariable = patron;: Aquí se asigna la misma referencia del objeto RegExppatrona la variableotraVariable.- Tanto
patroncomootraVariableapuntan al mismo objeto en la memoria.
- Intento de modificación del objeto RegExp:
patron.ignoreCase = false;: Aquí intentas modificar la propiedadignoreCasedel objeto RegExp. Sin embargo, las propiedades de un objeto RegExp comoignoreCase,global,multiline, etc., son de solo lectura y no pueden ser modificadas una vez que el objeto ha sido creado.- Esta línea no cambiará la propiedad
ignoreCasedel objeto RegExp.
- Uso del método
testdel objeto RegExp:console.log(otraVariable.test("HOLA"));: Este método verifica si la cadena «HOLA» coincide con el patrón de la expresión regular.- Dado que
patronyotraVariableapuntan al mismo objeto RegExp, yignoreCaseno se puede modificar, la expresión regular sigue siendo insensible a mayúsculas y minúsculas. Por lo tanto, el métodotestdevuelvetrue, nofalsecomo sugiere el comentario.
2. Diferencia clave entre los dos tipos de datos en JavaScript.
En JavaScript, los tipos de datos primitivos y los tipos de datos de referencia son dos categorías importantes que se comportan de manera diferente.
Siendo las mas importantes estas dos:
- Mutabilidad:
- Almacenamiento en memoria:
2.1. Mutabilidad en ambos tipos de datos:
2.1.1. Los datos primitivos son inmutables:
Lo que significa que una vez creado un valor, este no puede ser cambiado. Si intentas modificar un valor primitivo, en realidad estás creando un nuevo valor y asignándolo a la variable.
Esto es importante porque garantiza que los valores primitivos no cambian a menos que se les reasigne explícitamente un nuevo valor.
EJEMPLO:
let saludo = "Hola";
saludo[0] = "C";
console.log(saludo); // Output: "Hola"
saludo = "Chao"; //
console.log(saludo); // Output: "Chao"Lenguaje del código: JavaScript (javascript)
saludo[0] = "C":- Cuando intentas cambiar el primer carácter de la cadena «Hola», estás tratando de modificar directamente el valor de un tipo de dato primitivo. Sin embargo, los tipos primitivos son inmutables, por lo que esta operación no tiene ningún efecto. JavaScript simplemente ignora esta asignación.
saludo = "Chao":- Aquí estás haciendo una reasignación completa. En lugar de modificar el valor existente de
saludo, estás creando una nueva cadena («Chao») y asignando esa nueva referencia a la variablesaludo. La antigua cadena «Hola» queda en la memoria, pero ya no está referenciada por ninguna variable.
- Aquí estás haciendo una reasignación completa. En lugar de modificar el valor existente de
1.2.2. Los datos de referencia son mutables:
Los tipos de datos de referencia (como los objetos y arrays) son mutables, lo que significa que puedes cambiar sus propiedades o elementos sin cambiar la referencia misma.
Es decir, la referencia que una variable mantiene sigue apuntando al mismo lugar en la memoria, pero el contenido del objeto o array puede ser modificado.
EJEMPLO:
let persona = { nombre: "Ana", edad: 25 };
persona.edad = 26; // Modificación de la propiedad edad dentro del objeto
console.log(persona.edad); // Output: 26Lenguaje del código: JavaScript (javascript)
Explicación de la mutabilidad:
- Creación del objeto
persona:- Cuando creas
let persona = { nombre: "Ana", edad: 25 };, estás creando un objeto con dos propiedades:nombreyedad. - Este objeto es almacenado en la memoria heap, y la variable
personacontiene una referencia a la ubicación en la memoria donde se almacena el objeto.
- Cuando creas
- Modificación del objeto:
- La línea
persona.edad = 26;cambia el valor de la propiedadedaddentro del objeto. - Dado que los objetos en JavaScript son mutables, puedes modificar sus propiedades directamente, y esos cambios afectarán al mismo objeto en la memoria.
- La línea
- Acceso al objeto modificado:
- Cuando haces
console.log(persona.edad);, JavaScript accede al objeto referenciado porpersonay muestra el valor actualizado de la propiedadedad, que ahora es26.
- Cuando haces
2.2. Almacenamiento en memoria
2.2.1. Almacenamiento y comportamiento de los tipos de datos primitivos:
Los valores de los tipos de datos primitivos se almacenan directamente en la variable (y recuerda que son inmutables). Esto significa que cuando declaras una variable con un valor primitivo, ese valor se guarda directamente en el espacio de memoria asociado con la variable.
¿Y en que espacio de la memoria se almacenan específicamente?
Se almacenan en la memoria stack, que es una región de la memoria que maneja datos de tamaño fijo y acceso rápido.
Características de la Memoria Stack:
- Rápido acceso: Debido a su estructura LIFO (Last In, First Out), los valores se almacenan y recuperan rápidamente.
- Tamaño limitado: La stack tiene un tamaño limitado, por lo que es ideal para valores simples y de tamaño conocido.
- Valores únicos por variable: Cada variable tiene su propio espacio de memoria independiente en la stack, lo que significa que no hay referencias compartidas.
Ejemplo práctico:
let num1 = 5;
let num2 = num1;
num2 = 10;
console.log(num1); // Imprime 5
console.log(num2); // Imprime 10Lenguaje del código: JavaScript (javascript)
- En este ejemplo, cuando asignamos
num1anum2, se crea una copia independiente del valor 5. Luego, al cambiarnum2a 10, solo se modifica la variablenum2, dejando anum1sin cambios.
2.2.2. Almacenamiento y comportamiento de los tipos de datos de referencia:
Los tipos de datos de referencia NO almacenan el valor real directamente en la variable. En lugar de eso, la variable almacena una REFERENCIA (una dirección de memoria) que apunta al lugar en la MEMORI A HEAP donde el dato real (como un objeto o función) se almacena. Es por eso que se les llama «tipos de datos de referencia» y recuerda que esto datos son mutables.
Los tipos de datos de referencia se almacenan en la memoria heap, que es una región más grande y flexible destinada a almacenar datos dinámicos o de tamaño variable.
Cuando se declara una variable de tipo referencia (como un objeto o array), lo que se almacena en la variable es una referencia (dirección de memoria) que apunta al lugar en el heap donde el dato real está almacenado.
Características de la Memoria Heap:
- Tamaño flexible: A diferencia de la stack, el heap puede manejar datos de tamaño variable y no está limitado en la misma medida.
- Acceso más lento: Debido a su estructura menos organizada, acceder a datos en el heap es generalmente más lento que en la stack.
- Referencias compartidas: Varias variables pueden apuntar al mismo objeto en el heap, lo que permite la manipulación compartida de datos, pero también introduce el riesgo de efectos secundarios no deseados.
Ejemplo práctico:
let persona1 = { nombre: "Ana", edad: 25 };
let persona2 = persona1;
persona2.edad = 26;
console.log(persona1.edad); // Imprime 26
console.log(persona2.edad); // Imprime 26Lenguaje del código: JavaScript (javascript)
- Aquí,
persona1ypersona2apuntan al mismo objeto en memoria. Al modificarpersona2, también se modificapersona1, ya que ambas variables hacen referencia al mismo objeto.
Lo que debemos tener presente de estas diferencias es:
Datos primitivos:
- Son inmutables.
- Se almacenan directamente en la variable.
Datos de referencia:
- Son mnutables.
- La variable almacena una referencia que apunta al lugar en la memoria heap donde el dato real se almacena.
3. JavaScript: Un lenguaje dinámico y sus tipos de datos
La naturaleza dinámica de JavaScript es una de sus características más distintivas y tiene una estrecha relación con cómo maneja los tipos de datos.
3.1. ¿Qué significa que JavaScript sea un lenguaje dinámico?
Un lenguaje de programación es considerado dinámico cuando no requiere que se declare el tipo de dato de una variable antes de asignarle un valor. Esto significa que puedes asignar diferentes tipos de datos a la misma variable a lo largo de la ejecución del programa (ejemplo en el punto 3.5.).
En contraste con los lenguajes estáticos, como Java o C++, donde debes declarar el tipo de una variable al declararla, JavaScript te brinda más flexibilidad.
3.2. Relación con los tipos de datos:
La dinámica de JavaScript se manifiesta de varias formas en relación con los tipos de datos:
- Tipado débil:
- JavaScript no es estricto en cuanto a los tipos de datos. Puedes realizar operaciones entre diferentes tipos sin que el lenguaje te obligue a realizar conversiones explícitas. Por ejemplo, puedes sumar un número a una cadena, y JavaScript intentará convertir el número a una cadena antes de concatenarlas.
- Inferencia de tipos:
- JavaScript infiere el tipo de una variable en tiempo de ejecución según el valor que se le asigne. Esto significa que no necesitas declarar explícitamente el tipo de una variable.
- Cambio de tipo:
- El tipo de una variable puede cambiar durante la ejecución del programa. Puedes asignar un número a una variable y luego asignarle una cadena sin ningún problema.
3.3. Ventajas de la dinámica en JavaScript:
- Flexibilidad: Permite escribir código de forma más concisa y rápida.
- Adaptabilidad: Facilita la creación de código más flexible y adaptable a diferentes situaciones.
- Prototipado rápido: Ideal para el desarrollo rápido de aplicaciones web.
3.4. Desventajas de la dinámica en JavaScript:
- Posibles errores: La flexibilidad puede llevar a errores difíciles de detectar, como errores de tipo que pueden pasar desapercibidos hasta que se ejecute el código.
- Dificultad para depurar: Los errores de tipo pueden ser más difíciles de rastrear en comparación con lenguajes estáticamente tipados.
3.5. Ejemplo del tipado dinámico en JavaScript:
let miVariable = 10; //
console.log(typeof miVariable); //
miVariable = "Hola";
console.log(typeof miVariable); Lenguaje del código: JavaScript (javascript)
En este ejemplo:
- La variable
miVariablecambia de tipo de número (10) a cadena («Hola») sin ningún problema realizando una reasignación de valor.- Em un lenguaje estático, para cambiar el tipo de dato, es necesario declarar una nueva variable con el tipo deseado y asignarle el valor correspondiente.
- No se especifica el tipo de dato al declarar la variable, o sea, al declarar la variable número (10) no es necesario especificar de que tipo de dato de que se trata (number). Como si se hace en otros lenguajes de tipado estático como java.
3.6. ¿Cómo hago para saber que tipo de dato estoy declarando en JavaScript? – Operador typeof:
La forma más común y directa de determinar el tipo de dato de una variable es utilizando el operador typeof. Este operador devuelve una cadena que indica el tipo de dato.
Ejemplo:
let numero = 42;
let texto = "Hola";
let booleano = true;
let nulo = null;
let indefinido;
let objeto = {};
console.log(typeof numero); // Output: "number"
console.log(typeof texto); // Output: "string"
console.log(typeof booleano); // Output: "boolean"
console.log(typeof nulo); // Output: "object" (Un error histórico de JavaScript)
console.log(typeof indefinido); // Output: "undefined"
console.log(typeof objeto); // Output: "object"Lenguaje del código: JavaScript (javascript)
- Como vemos en el ejemplo, usando
concole.log (typeof nombre_de_la_variable), se imprime el tipo de dato manipulado. - Útil cuando revisamos un código y tenemos dudas del tipo de variable que esta usando una variable!!
Consideraciones importantes usando el operador typeof:
null: Aunquenullrepresenta la ausencia de valor,typeof nulldevuelve «object». Este es un error histórico en JavaScript.- Arrays: Los arrays son un tipo especial de objeto, por lo que
typeofdevuelve «object». - Funciones: Las funciones también son objetos en JavaScript, por lo que
typeofdevuelve «function». - Objetos personalizados: Cualquier objeto que crees será de tipo «object».
Otras formas de verificar tipos sin usar operador typeof (menos comunes):
- Constructor: Aunque no es muy recomendado, puedes usar el constructor de un objeto para verificar su tipo. Por ejemplo,
numero instanceof Number. Sin embargo, esto puede llevar a resultados inesperados en algunos casos. - Funciones de utilidad: Algunas bibliotecas proporcionan funciones más sofisticadas para verificar tipos, pero
typeofsuele ser suficiente para la mayoría de los casos.
RECUERDA: La naturaleza dinámica de JavaScript, junto con su sistema de tipos débil, permite una gran flexibilidad pero también requiere una atención especial a los posibles errores de tipo. Comprender estos conceptos es fundamental para escribir código JavaScript de manera efectiva y evitar problemas comunes.
4. ¿Por qué es importante conocer el tipo de dato en JavaScript?
Conocer el tipo de dato en JavaScript es fundamental para escribir código eficiente y evitar errores comunes. Aquí te explico por qué:
- Operaciones:
- Operadores aritméticos: Se comportan de manera diferente según el tipo de dato. Sumar dos números es distinto a concatenar dos cadenas.
- Operadores lógicos: Se utilizan para comparar valores y tomar decisiones, pero el comportamiento varía según si se compara un número, una cadena o un booleano.
- Operadores de comparación: Los operadores de comparación (
==,===) tienen comportamientos diferentes cuando se comparan distintos tipos de datos. - Descubre los principales operadores JavaScript:
- Condicionales:
- Toma de decisiones: Los condicionales (if, else) se basan en expresiones que evalúan a un valor booleano (true o false). El tipo de dato de las variables involucradas en la expresión condicional influye en el resultado.
- Funciones:
- Parámetros y retorno: Las funciones esperan recibir parámetros de un tipo de dato específico y pueden devolver un resultado de un tipo determinado.
- Sobrecarga de funciones: Aunque JavaScript no tiene sobrecarga de funciones como en otros lenguajes, conocer el tipo de dato de los argumentos puede ayudarte a escribir funciones más flexibles.
- Conversión de tipos:
- Coerción: JavaScript realiza conversiones de tipo de forma automática en ciertas situaciones, pero es importante entender cómo funciona para evitar resultados inesperados.
- Conversión explícita: En ocasiones, es necesario realizar conversiones de tipo de forma explícita utilizando funciones como
Number(),String(),Boolean().
- Optimización del código:
- Algoritmos: La elección del algoritmo adecuado depende en gran medida de los tipos de datos que se están procesando.
- Estructuras de datos: El uso de estructuras de datos adecuadas (arrays, objetos, etc.) también está relacionado con el tipo de datos que se va a almacenar.
En resumen, conocer el tipo de dato en JavaScript te permite:
- Escribir código más claro y conciso.
- Evitar errores comunes.
- Optimizar el rendimiento de tu código.
- Comprender mejor el comportamiento de JavaScript.
5. Preguntas frecuentes y resumen sobre los tipos de datos en JS.
Los tipos de datos primitivos en JavaScript son string, number, boolean, null, undefined y symbol. Estos datos se almacenan directamente en la memoria y no tienen métodos ni propiedades.
El tipo number representa valores numéricos, tanto enteros como decimales. Se usa para cálculos matemáticos, por ejemplo: let x = 42; o let y = 3.14;.
El tipo string representa texto y se define con comillas simples o dobles. Ejemplo: let saludo = "Hola"; o let nombre = 'Manuel';.
El tipo boolean solo tiene dos valores: true o false. Se usa en comparaciones y estructuras de control, por ejemplo: let esMayor = 10 > 5;.
El valor null representa la ausencia intencional de un valor. Ejemplo: let dato = null;. Se usa para indicar que una variable está vacía o sin valor asignado.
El valor undefined indica que una variable ha sido declarada pero no tiene un valor asignado. Ejemplo: let x; (su valor será undefined).
Para conocer el tipo de dato de una variable, usa typeof. Ejemplo: console.log(typeof 42); // "number".
Para convertir datos, usa funciones como String(), Number() y Boolean(). Ejemplo: let num = Number("10");.
