Variables y tipos
Los fundamentos de las variables modernas
JavaScript moderno: variables, tipos y estructuras de datos
En este tutorial vamos a explorar los fundamentos del JavaScript moderno: cómo declarar variables, comprender los distintos tipos de datos, manipular los operadores y utilizar las estructuras de datos esenciales.
JavaScript es un lenguaje dinámico y flexible que ha evolucionado considerablemente desde su creación. Con la llegada de ES6 (ECMAScript 2015) y de las versiones posteriores, el lenguaje ofrece ahora funcionalidades potentes y modernas.
Declaración de variables
En JavaScript moderno, existen tres formas de declarar variables:
let
let permite declarar variables cuyo ámbito se limita al bloque en el que están definidas:
let age = 25;
age = 26; // Reasignación posible
if (true) {
let message = "Hello"; // Variable limitada a este bloque
console.log(message); // "Hello"
}
// console.log(message); // Error: message no está definido
const
const permite declarar constantes cuyo valor no puede reasignarse:
const PI = 3.14159;
// PI = 3.14; // Error: no se puede reasignar una constante
const personne = { nom: "Alice" };
personne.nom = "Bob"; // Posible: lo que puede cambiar es el contenido
// personne = {}; // Error: no se puede reasignar la referencia
var (método antiguo)
var era la única forma de declarar variables antes de ES6. Su ámbito se limita a la función o es global:
var x = 10;
var x = 20; // Redeclaración posible (problemática)
if (true) {
var y = 30; // Ámbito no limitado al bloque
}
console.log(y); // 30 - y es accesible aquí
Buenas prácticas
En JavaScript moderno, es preferible:
constpor defecto para toda variable que no vaya a reasignarseletcuando sea necesaria la reasignación- Evitar
var, salvo que trabajes con código legacy
Tipos de datos
JavaScript es un lenguaje de tipado dinámico, lo que significa que no es necesario declarar el tipo de una variable.
Tipos primitivos
1. Number
JavaScript utiliza un único tipo para todos los números:
const entier = 42;
const decimal = 3.14;
const exponentiel = 2.5e5; // 250000
const binaire = 0b1010; // 10
const octal = 0o744; // 484
const hexadecimal = 0xFF; // 255
// Valores especiales
const infini = Infinity;
const pasUnNombre = NaN; // Not a Number
// Comprobaciones
console.log(isNaN(pasUnNombre)); // true
console.log(isFinite(infini)); // false
2. String (cadena de caracteres)
JavaScript ofrece varias formas de crear cadenas:
// Comillas simples
const prenom = 'Marie';
// Comillas dobles
const nom = "Dupont";
// Template literals (backticks) - ES6
const age = 30;
const message = `${prenom} ${nom} a ${age} ans.`;
// Métodos útiles
console.log(prenom.toUpperCase()); // MARIE
console.log(" texte ".trim()); // "texte"
console.log("abc,def".split(",")); // ["abc", "def"]
console.log("Hello".includes("ell")); // true
3. Boolean
const estMajeur = true;
const estInscrit = false;
// Expresiones condicionales
const a = 5;
const b = 10;
console.log(a < b); // true
console.log(a === b); // false (igualdad estricta)
console.log(a >= 5); // true
4. Undefined
undefined representa una variable declarada pero sin valor asignado:
let resultat;
console.log(resultat); // undefined
// Comprobación
console.log(typeof resultat === 'undefined'); // true
5. Null
null representa la ausencia deliberada de valor:
const donnees = null;
// Cuidado con la trampa
console.log(typeof null); // "object" (bug histórico de JavaScript)
console.log(donnees === null); // true (utilizar la igualdad estricta)
6. Symbol (ES6)
Symbol crea identificadores únicos e inmutables:
const id1 = Symbol('id');
const id2 = Symbol('id');
console.log(id1 === id2); // false - cada Symbol es único
7. BigInt (ES2020)
Para representar enteros de tamaño arbitrario:
const grandNombre = 1234567890123456789012345678901234567890n;
const autreFacon = BigInt("9007199254740991");
console.log(typeof grandNombre); // "bigint"
Tipos por referencia (objetos)
1. Object
Los objetos son colecciones de pares clave-valor:
// Creación de un objeto literal
const personne = {
prenom: "Jean",
nom: "Dupont",
age: 30,
adresse: {
ville: "Paris",
codePostal: "75001"
}
};
// Acceso a las propiedades
console.log(personne.prenom); // "Jean"
console.log(personne["nom"]); // "Dupont"
// Adición/modificación de propiedades
personne.email = "jean.dupont@example.com";
personne.age = 31;
// Métodos de objetos
const cles = Object.keys(personne); // ["prenom", "nom", "age", "adresse", "email"]
const valeurs = Object.values(personne); // ["Jean", "Dupont", 31, {...}, "jean..."]
2. Array
Los arrays son colecciones ordenadas de valores:
// Creación de un array
const fruits = ["pomme", "banane", "cerise"];
const mixte = [1, "deux", true, null, { clé: "valeur" }];
// Acceso a los elementos (indexados a partir de 0)
console.log(fruits[0]); // "pomme"
// Métodos útiles
fruits.push("orange"); // Añade al final
fruits.pop(); // Elimina el último elemento
fruits.unshift("fraise"); // Añade al principio
fruits.shift(); // Elimina el primer elemento
// Bucle forEach
fruits.forEach((fruit, index) => {
console.log(`${index}: ${fruit}`);
});
// Métodos de transformación (no modifican el array original)
const fruitsMajuscules = fruits.map(fruit => fruit.toUpperCase());
const fruitsCourts = fruits.filter(fruit => fruit.length < 6);
const total = [1, 2, 3, 4].reduce((acc, val) => acc + val, 0); // 10
3. Function
En JavaScript, las funciones son objetos de primera clase:
// Declaración de función
function saluer(nom) {
return `Bonjour, ${nom} !`;
}
// Expresión de función
const direAuRevoir = function(nom) {
return `Au revoir, ${nom} !`;
};
// Función flecha (ES6)
const multiplier = (a, b) => a * b;
// Función como parámetro
function executerFonction(fn, valeur) {
return fn(valeur);
}
console.log(executerFonction(saluer, "Marie")); // "Bonjour, Marie !"
4. Date
const maintenant = new Date();
const dateSpecifique = new Date("2023-12-31T23:59:59");
const timestamp = dateSpecifique.getTime(); // milisegundos desde el 1 de enero de 1970
5. Map y Set (ES6)
// Map - colección de pares clave-valor (claves de cualquier tipo)
const utilisateurs = new Map();
utilisateurs.set('u1', { nom: "Alice", age: 25 });
utilisateurs.set('u2', { nom: "Bob", age: 30 });
// Set - colección de valores únicos
const nombres = new Set([1, 2, 3, 3, 4, 4, 5]); // {1, 2, 3, 4, 5}
Comprobación de tipos
Para comprobar el tipo de una variable, utiliza el operador typeof:
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof { a: 1 }); // "object"
console.log(typeof [1, 2, 3]); // "object" (los arrays son objetos en JS)
console.log(typeof function() {}); // "function"
Para los arrays, utiliza Array.isArray():
console.log(Array.isArray([1, 2, 3])); // true
Conversión de tipos
JavaScript realiza a menudo conversiones implícitas, pero también puedes hacerlas de forma explícita:
// Conversión a cadena
const num = 42;
const numStr = String(num); // "42"
const autreMethode = num.toString(); // "42"
// Conversión a número
const str = "42";
const strNum = Number(str); // 42
const parseMethode = parseInt(str, 10); // 42 (base 10)
const parseFloat = parseFloat("3.14"); // 3.14
// Conversión a booleano
const valeurBool = Boolean(1); // true
// false para: 0, "", null, undefined, NaN, false
Operadores
Operadores aritméticos
const a = 10;
const b = 3;
const addition = a + b; // 13
const soustraction = a - b; // 7
const multiplication = a * b; // 30
const division = a / b; // 3.3333...
const modulo = a % b; // 1 (resto de la división)
const puissance = a ** b; // 1000 (ES2016)
// Incremento y decremento
let compteur = 0;
compteur++; // compteur = 1
compteur--; // compteur = 0
Operadores de comparación
const a = 10;
const b = "10";
// Igualdad (con conversión de tipo)
console.log(a == b); // true
// Igualdad estricta (sin conversión)
console.log(a === b); // false
// Desigualdad (con conversión)
console.log(a != b); // false
// Desigualdad estricta (sin conversión)
console.log(a !== b); // true
// Comparaciones
console.log(a > 5); // true
console.log(a <= 10); // true
Operadores lógicos
const x = true;
const y = false;
// AND lógico
console.log(x && y); // false
// OR lógico
console.log(x || y); // true
// NOT lógico
console.log(!x); // false
// Cortocircuito (útil para valores por defecto)
const nom = null;
const nomAffiche = nom || "Utilisateur inconnu"; // "Utilisateur inconnu"
Operador de coalescencia nula (ES2020)
const valeur = null;
const resultat = valeur ?? "Valeur par défaut"; // "Valeur par défaut"
// Se diferencia de || en que solo usa el valor por defecto si el valor es null o undefined
Operador de encadenamiento opcional (ES2020)
const utilisateur = {
profil: {
// adresse: { ville: "Paris" }
}
};
// Sin encadenamiento opcional (riesgo de error)
// const ville = utilisateur.profil.adresse.ville; // ¡Error!
// Con encadenamiento opcional
const ville = utilisateur.profil?.adresse?.ville; // undefined
Operador de propagación (spread)
// Para los arrays
const tab1 = [1, 2, 3];
const tab2 = [...tab1, 4, 5]; // [1, 2, 3, 4, 5]
// Para los objetos
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
Desestructuración (ES6)
La desestructuración permite extraer valores de arrays o de objetos de forma concisa:
// Desestructuración de array
const nombres = [1, 2, 3, 4, 5];
const [premier, deuxieme, ...reste] = nombres;
console.log(premier); // 1
console.log(deuxieme); // 2
console.log(reste); // [3, 4, 5]
// Desestructuración de objeto
const personne = { prenom: "Alice", nom: "Dupont", age: 30 };
const { prenom, age, profession = "Inconnue" } = personne;
console.log(prenom); // "Alice"
console.log(age); // 30
console.log(profession); // "Inconnue" (valor por defecto)
// Renombrado de propiedades
const { prenom: firstName } = personne;
console.log(firstName); // "Alice"
// Desestructuración anidada
const utilisateur = {
id: 1,
infos: {
nom: "Durand",
contact: {
email: "durand@example.com"
}
}
};
const { infos: { contact: { email } } } = utilisateur;
console.log(email); // "durand@example.com"
Estructuras de control
JavaScript ofrece las estructuras de control habituales con algunas particularidades modernas.
Condicionales
// if, else if, else
const age = 18;
if (age < 18) {
console.log("Mineur");
} else if (age === 18) {
console.log("Tout juste majeur");
} else {
console.log("Majeur");
}
// Operador ternario
const statut = age >= 18 ? "majeur" : "mineur";
Bucles
// for clásico
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
// for...of (para iterar sobre los valores de un iterable)
const fruits = ["pomme", "banane", "cerise"];
for (const fruit of fruits) {
console.log(fruit);
}
// for...in (para iterar sobre las propiedades de un objeto)
const personne = { nom: "Dupont", prenom: "Jean", age: 30 };
for (const prop in personne) {
console.log(`${prop}: ${personne[prop]}`);
}
// while
let compteur = 0;
while (compteur < 5) {
console.log(compteur);
compteur++;
}
// do...while
let i = 0;
do {
console.log(i);
i++;
} while (i < 5);
Switch
const jour = "Lundi";
switch (jour) {
case "Lundi":
console.log("Début de semaine");
break;
case "Mercredi":
console.log("Milieu de semaine");
break;
case "Vendredi":
console.log("Fin de semaine");
break;
default:
console.log("Autre jour");
}
Entradas y salidas básicas
Consola
// Visualización
console.log("Message simple");
console.info("Information");
console.warn("Avertissement");
console.error("Erreur");
// Visualización con formato
console.log("Nom: %s, Âge: %d", "Alice", 30);
// Agrupación
console.group("Détails utilisateur");
console.log("Nom: Alice");
console.log("Âge: 30");
console.groupEnd();
// Tabla
console.table([
{ nom: "Alice", age: 25 },
{ nom: "Bob", age: 30 }
]);
// Medición del tiempo
console.time("Timer");
// Operaciones largas...
console.timeEnd("Timer"); // Muestra el tiempo transcurrido
Interacción con el usuario (navegador)
// Mostrar un mensaje
alert("Attention !");
// Pedir una confirmación
const confirmation = confirm("Êtes-vous sûr ?");
if (confirmation) {
console.log("L'utilisateur a confirmé");
}
// Pedir una entrada
const nom = prompt("Quel est votre nom ?", "Utilisateur");
console.log(`Bonjour, ${nom}`);
Ejemplo completo
A continuación, un ejemplo que utiliza varios de los conceptos que hemos aprendido:
// Programa que calcula la media de una lista de números
// Definición de una función flecha para calcular la media
const calculerMoyenne = (nombres) => {
if (nombres.length === 0) return 0;
const somme = nombres.reduce((acc, val) => acc + val, 0);
return somme / nombres.length;
};
// Función para comparar un número con la media
const comparerAvecMoyenne = (nombre, moyenne) => {
if (nombre > moyenne) return "supérieur à";
if (nombre < moyenne) return "inférieur à";
return "égal à";
};
// Programa principal
try {
// En un entorno real, estos valores podrían venir de una interfaz de usuario
const nombres = [15, 20, 25, 10, 30];
// Mostrar los números
console.log("Nombres:", nombres.join(", "));
// Calcular y mostrar la media
const moyenne = calculerMoyenne(nombres);
console.log(`La moyenne est: ${moyenne.toFixed(2)}`);
// Comparar cada número con la media
console.log("\nComparaison avec la moyenne:");
nombres.forEach((nombre, index) => {
const relation = comparerAvecMoyenne(nombre, moyenne);
console.log(`Nombre ${index + 1} (${nombre}) est ${relation} la moyenne.`);
});
// Filtrar los números superiores a la media
const nombresSuperieurs = nombres.filter(nombre => nombre > moyenne);
console.log(`\nNombres supérieurs à la moyenne: ${nombresSuperieurs.join(", ")}`);
} catch (erreur) {
console.error("Une erreur est survenue:", erreur.message);
}
Las diferencias clave con otros lenguajes
Si conoce otros lenguajes de programación, estas son algunas diferencias notables en JavaScript:
-
Tipado dinámico: no hace falta declarar los tipos, que se determinan en tiempo de ejecución.
-
Funciones como objetos de primera clase: las funciones pueden asignarse a variables, pasarse como argumentos y ser devueltas por otras funciones.
-
Prototipos frente a clases: JavaScript utiliza un sistema basado en prototipos, aunque la sintaxis de clases se introdujo en ES6.
-
Hoisting: las declaraciones de variables y de funciones se «elevan» a la parte superior de su ámbito.
-
Eventos y callbacks: JavaScript utiliza mucho los callbacks y las promesas para gestionar la asincronía.
-
Igualdad laxa frente a estricta:
==realiza una conversión de tipo, mientras que===no la realiza.
Buenas prácticas
Para escribir JavaScript moderno limpio y mantenible:
-
Utilice
constpor defecto,letsi necesita reasignar, y evitevar. -
Prefiera las funciones flecha para las funciones cortas y los callbacks.
-
Utilice la desestructuración para extraer valores de objetos o arrays.
-
Aplique las template literals para las cadenas multilínea o con interpolación.
-
Evite las comparaciones laxas (
==,!=) y prefiera las comparaciones estrictas (===,!==). -
Utilice los parámetros por defecto y los operadores de propagación.
-
Adopte los métodos modernos de array como
map,filteryreduceen lugar de los bucles tradicionales cuando sea apropiado. -
Respete la asincronía con Promises y async/await (que abordaremos en un próximo tutorial).
Ejercicios prácticos
Para consolidar sus conocimientos, pruebe estos ejercicios:
-
Escriba una función que reciba un array de números y devuelva la suma de los números pares.
-
Cree un objeto que represente un libro con propiedades como el título, el autor y un método para mostrar esa información.
-
Escriba una función que reciba una cadena y devuelva un objeto con el número de apariciones de cada carácter.
-
Cree una función que convierta una temperatura de Celsius a Fahrenheit o viceversa, según un parámetro de modo.
-
Utilice la desestructuración para intercambiar los valores de dos variables sin usar una variable temporal.
Conclusión
En este tutorial hemos explorado los fundamentos del JavaScript moderno:
- Las distintas formas de declarar variables (
let,const,var) - Los tipos de datos (primitivos y por referencia)
- Los operadores (aritméticos, de comparación, lógicos)
- La desestructuración y los operadores de propagación
- Las estructuras de control (condicionales y bucles)
- Las entradas/salidas básicas
Estos conceptos constituyen los cimientos sobre los que construirá su comprensión del JavaScript moderno. A medida que avance, descubrirá cómo estos elementos se combinan para crear aplicaciones web dinámicas e interactivas.
En el próximo tutorial exploraremos las funciones modernas y sus nuevas características.
¿Necesita repasar los conceptos básicos? Consulte nuestro tutorial de introducción.
¿Listo para continuar? Pase al próximo tutorial sobre funciones.
Comentarios
Los comentarios funcionan con GitHub Discussions
Inicia sesión con GitHub para participar en la discusión