0%
JavaScript moderno: variables con let y const

Variables y tipos

Los fundamentos de las variables modernas

10-15 min

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:

  • const por defecto para toda variable que no vaya a reasignarse
  • let cuando 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:

  1. Tipado dinámico: no hace falta declarar los tipos, que se determinan en tiempo de ejecución.

  2. Funciones como objetos de primera clase: las funciones pueden asignarse a variables, pasarse como argumentos y ser devueltas por otras funciones.

  3. Prototipos frente a clases: JavaScript utiliza un sistema basado en prototipos, aunque la sintaxis de clases se introdujo en ES6.

  4. Hoisting: las declaraciones de variables y de funciones se «elevan» a la parte superior de su ámbito.

  5. Eventos y callbacks: JavaScript utiliza mucho los callbacks y las promesas para gestionar la asincronía.

  6. 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:

  1. Utilice const por defecto, let si necesita reasignar, y evite var.

  2. Prefiera las funciones flecha para las funciones cortas y los callbacks.

  3. Utilice la desestructuración para extraer valores de objetos o arrays.

  4. Aplique las template literals para las cadenas multilínea o con interpolación.

  5. Evite las comparaciones laxas (==, !=) y prefiera las comparaciones estrictas (===, !==).

  6. Utilice los parámetros por defecto y los operadores de propagación.

  7. Adopte los métodos modernos de array como map, filter y reduce en lugar de los bucles tradicionales cuando sea apropiado.

  8. 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:

  1. Escriba una función que reciba un array de números y devuelva la suma de los números pares.

  2. Cree un objeto que represente un libro con propiedades como el título, el autor y un método para mostrar esa información.

  3. Escriba una función que reciba una cadena y devuelva un objeto con el número de apariciones de cada carácter.

  4. Cree una función que convierta una temperatura de Celsius a Fahrenheit o viceversa, según un parámetro de modo.

  5. 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

¡Enlace copiado!