Saltar al contenido principal

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:

  • let
  • const
  • 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]