ES6+
JavaScript ha ido evolucionando con el tiempo y ha incorporado nuevas características que hacen que el código sea más sencillo, legible y cómodo de escribir.
Una de las versiones más importantes fue ES6, publicada en 2015. A partir de ella se fueron incorporando nuevas funcionalidades al lenguaje.
En esta lección veremos algunas de las características más utilizadas de JavaScript moderno:
letconst- Arrow functions
- Template literals
- Destructuring
- Spread
- Rest
- Default parameters
Algunas de ellas ya las hemos visto puesto que ya están más arraigadas (let, const, arrow functions...). Vamos a ver aquí nuevas buenas prácticas del ES6+.
Destructuring
El destructuring permite extraer valores de arrays u objetos y guardarlos directamente en variables.
Esto resulta especialmente útil cuando trabajamos con datos complejos.
Destructuring de arrays
Supongamos que tenemos:
const numeros = [10, 20, 30];
Con Destructuring podemos obtener los valores individualmente de esta manera:
const [primero, segundo, tercero] = numeros;
console.log(primero);
console.log(segundo);
console.log(tercero);
Salida:
10
20
30
La posición de cada variable coincide con la posición del elemento en el array.
numeros
↓
[10, 20, 30]
↓ ↓ ↓
↓ ↓ ↓
primero segundo tercero
Sería como hacer de la forma tradicional:
let primero = numeros[0];
let segundo = numeros[1];
let tercero = numeros[2];
console.log(primero);
console.log(segundo);
console.log(tercero);
También podemos ignorar elementos dejando espacio en blanco entre las comas:
const [primero, , tercero] = numeros;
console.log(primero);
console.log(tercero);
Salida:
10
30
Destructuring de objetos
También podemos extraer propiedades de un objeto.
const persona = {
nombre: "Ana",
edad: 25,
ciudad: "Valencia"
};
const { nombre, edad } = persona;
console.log(nombre);
console.log(edad);
Salida:
Ana
25
En este caso, los nombres de las variables coinciden con los nombres de las propiedades.
Podemos visualizarlo así:
persona
├── nombre → "Ana"
└── edad → 25
↓ destructuring
nombre = "Ana"
edad = 25
También podemos cambiar el nombre de la variable:
const { nombre: nombrePersona } = persona;
console.log(nombrePersona);
Salida:
Ana
Aquí nombre es la propiedad del objeto y nombrePersona es la variable que hemos creado.
Spread ...
El operador spread (...) permite expandir los elementos de un array o las propiedades de un objeto.
Aunque utiliza tres puntos, su comportamiento depende de dónde lo utilicemos.
Spread con arrays
Supongamos que tenemos:
const numeros = [1, 2, 3];
Podemos crear otro array utilizando sus elementos:
const nuevosNumeros = [...numeros, 4, 5];
console.log(nuevosNumeros);
Salida:
[1, 2, 3, 4, 5]
El ...numeros introduce dentro del nuevo array todos los elementos de numeros.
Sería equivalente a escribir de la forma tradicional:
const numeros = [1, 2, 3];
const nuevosNumeros = numeros.slice(); // copia superficial
nuevosNumeros.push(4, 5);
console.log(nuevosNumeros);
También podemos combinar arrays:
const numeros1 = [1, 2, 3];
const numeros2 = [4, 5, 6];
const todos = [...numeros1, ...numeros2];
console.log(todos);
Salida:
[1, 2, 3, 4, 5, 6]
Copiar un array
También podemos utilizar spread para crear una copia:
const numeros = [1, 2, 3];
const copia = [...numeros];
Ahora tenemos dos arrays independientes:
copia.push(4);
console.log(numeros);
console.log(copia);
Salida:
[1, 2, 3]
[1, 2, 3, 4]
Spread con objetos
También podemos expandir las propiedades de un objeto:
const persona = {
nombre: "Paula",
edad: 25
};
const personaCompleta = {
...persona,
ciudad: "Valencia"
};
console.log(personaCompleta);
Resultado:
{
nombre: "Paula",
edad: 25,
ciudad: "Valencia"
}
También podemos utilizarlo para crear una copia de un objeto:
const copia = { ...persona };
Rest ...
El operador rest también utiliza ..., pero en este caso sirve para recoger varios valores en un único array.
Por ejemplo:
function sumar(...numeros) {
console.log(numeros);
}
sumar(10, 20, 30, 40);
Salida:
[10, 20, 30, 40]
Todos los argumentos se han recogido dentro del array numeros. Si no utilizasemos esta estrucutura sería así:
function sumar(numeros) {
console.log(numeros);
}
sumar([10, 20, 30, 40]);
Observa que el cambio es simplemente que usando ... al llamar a la función podemos pasarle los números como varios argumentos distintos separados con comas. Si lo hacemos de la manera tradicional solo le pasamos un parámetro de tipo array. Ambas son válidas, simplemente dependiendo de la situación puede ser más cómoda una u otra.
Podemos combinarlo con parámetros normales, que no llevarían ...:
function mostrarDatos(nombre, ...edades) {
console.log(nombre);
console.log(edades);
}
mostrarDatos("Paula", 20, 25, 30);
Salida:
Paula
[20, 25, 30]
El primer argumento se guarda en nombre y todos los argumentos restantes se guardan en edades.
Spread vs Rest
Aunque utilizan la misma sintaxis (...), debemos distinguirlos.
Spread → expande
const numeros = [1, 2, 3];
const copia = [...numeros];
Los elementos del array se expanden.
Rest → recoge
function mostrar(...numeros) {
console.log(numeros);
}
Los argumentos se recogen en un array.
Podemos recordarlo así:
Spread → ... → expande
Rest → ... → recoge
Default parameters
Los parámetros por defecto permiten establecer un valor que se utilizará cuando no proporcionemos un argumento.
Por ejemplo:
function saludar(nombre = "usuario") {
console.log(`Hola ${nombre}`);
}
Si proporcionamos un nombre:
saludar("Miguel");
Salida:
Hola Miguel
Pero si no proporcionamos ninguno:
saludar();
Salida:
Hola usuario
El valor "usuario" es el valor por defecto.
Ejemplo con varios parámetros
function crearProducto(nombre, precio = 0, disponible = true) {
console.log(nombre);
console.log(precio);
console.log(disponible);
}
crearProducto("Ratón");
Salida:
Ratón
0
true
Los parámetros que no hemos proporcionado utilizan sus valores por defecto.
Resumen
ES6+ incorpora muchas características que facilitan el trabajo con JavaScript.
let
Permite declarar variables cuyo valor puede cambiar.
let edad = 25;
edad = 26;
const
Permite declarar variables que no serán reasignadas.
const nombre = "Ana";
Arrow functions
Permiten escribir funciones de forma más corta.
const doble = numero => numero * 2;
Template literals
Permiten crear cadenas de texto con variables fácilmente.
`Hola ${nombre}`
Destructuring
Permite extraer valores de arrays y objetos.
const { nombre, edad } = persona;
Spread
Permite expandir arrays u objetos.
const copia = [...numeros];
Rest
Permite recoger varios valores en un array.
function sumar(...numeros) {
// ...
}
Default parameters
Permiten establecer valores por defecto para los parámetros.
function saludar(nombre = "usuario") {
// ...
}
Todas estas características aparecen constantemente en proyectos modernos de JavaScript, especialmente cuando trabajamos con arrays, objetos, funciones y APIs.
Ejemplos resueltos
Ejercicio resuelto 1 - Destructuring de un objeto
Enunciado
Tenemos un objeto con información de un producto. Extrae su nombre y precio utilizando destructuring y muestra un mensaje con template literals.
Solución
const producto = {
nombre: "Teclado",
precio: 45
};
const { nombre, precio } = producto;
console.log(`El ${nombre} cuesta ${precio} €`);
Salida:
El Teclado cuesta 45 €
Ejercicio resuelto 2 - Copiar y modificar un objeto
Enunciado
Tenemos un objeto con información de una persona. Crea un nuevo objeto utilizando spread y añade una nueva propiedad activo.
Solución
const persona = {
nombre: "Ana",
edad: 25
};
const usuario = {
...persona,
activo: true
};
console.log(usuario);
Resultado:
{
nombre: "Ana",
edad: 25,
activo: true
}
El objeto original no se modifica.
Ejercicio resuelto 3 - Función con parámetros por defecto y rest
Enunciado
Crea una función que reciba un nombre y cualquier cantidad de números. Si no se proporciona un nombre, debe utilizar "Usuario".
Solución
function mostrarNumeros(nombre = "Usuario", ...numeros) {
console.log(`${nombre}:`);
console.log(numeros);
}
mostrarNumeros("Ana", 10, 20, 30);
Salida:
Ana:
[10, 20, 30]
Si no proporcionamos el nombre:
mostrarNumeros(undefined, 10, 20, 30);
Salida:
Usuario:
[10, 20, 30]