informatica:programacion:cursos:programacion_avanzada_javascript:desestructuracion
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Próxima revisión | Revisión previa | ||
| informatica:programacion:cursos:programacion_avanzada_javascript:desestructuracion [2024/10/17 10:24] – creado tempwin | informatica:programacion:cursos:programacion_avanzada_javascript:desestructuracion [2024/10/17 12:42] (actual) – [DEMO: Parámetros rest] tempwin | ||
|---|---|---|---|
| Línea 3: | Línea 3: | ||
| Módulo perteneciente al curso [[informatica: | Módulo perteneciente al curso [[informatica: | ||
| + | ===== Interpolación de cadenas ===== | ||
| + | |||
| + | La interpolación de cadenas es una pequeña novedad de ECMAScript 2015, que a pesar de ser //syntactic sugar// puro, seguro que se convertirá en una de tus novedades favoritas. | ||
| + | |||
| + | Actualmente en JavaScript podemos crear cadenas de dos formas, ya sea con comillas dobles ('' | ||
| + | |||
| + | <code javascript> | ||
| + | var str = " | ||
| + | var str2 = ' | ||
| + | var str3 = 'Hello " | ||
| + | var str4 = "Hello \" | ||
| + | </ | ||
| + | |||
| + | Como se puede observar las versiones que no requieren //escapar// ningún carácter, son más legibles. Esa es la razón principal por la cual existen dos delimitadores distintos para una cadena: elige el que prefieras y usa el otro dentro. | ||
| + | |||
| + | <WRAP center round tip 60%> | ||
| + | Si alguna vez construyes JSON de forma manual (aunque no deberías hacerlo nunca, sino que deberías usar '' | ||
| + | </ | ||
| + | |||
| + | ==== Interpolando cadenas ==== | ||
| + | |||
| + | Bajo el nombre de " | ||
| + | |||
| + | Veamos cómo podríamos hacer eso en ECMAScript 5: | ||
| + | |||
| + | <code javascript> | ||
| + | String.prototype.format = function() { | ||
| + | var args = arguments; | ||
| + | return this.replace(/ | ||
| + | return typeof args[number] != ' | ||
| + | ? args[number] | ||
| + | : match | ||
| + | ; | ||
| + | }); | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | Este código añade al '' | ||
| + | |||
| + | <code javascript> | ||
| + | var str = " | ||
| + | </ | ||
| + | |||
| + | El valor de '' | ||
| + | |||
| + | Tener un método para interpolar cadenas nos evita tener que usar concatenaciones que al final terminan ensuciando mucho el código. | ||
| + | |||
| + | Pues bien en ECMAScript 2015 las tenemos de serie, en el lenguaje. Sin necesidad de invocar a función alguna y ¡encima con más potencia! Observa el siguiente código: | ||
| + | |||
| + | <code javascript> | ||
| + | var a0 = " | ||
| + | var a1 = 5; | ||
| + | var a2 = 2015; | ||
| + | var str=`${a0} ${a1} mola mucho, pero ${a0} ${a2} todavía mola más`; | ||
| + | </ | ||
| + | |||
| + | Este código deja en '' | ||
| + | |||
| + | Fijémonos en los detalles: | ||
| + | |||
| + | * Se usa **un nuevo delimitador de cadenas: la tilde abierta ('' | ||
| + | * Se usa '' | ||
| + | |||
| + | Veamos otro código que deje claro la evaluación de expresiones dentro de los // | ||
| + | |||
| + | <code javascript> | ||
| + | var a = 10; | ||
| + | var b = 32; | ||
| + | var str = `El resultado de sumar ${a} y ${b} es ${a+b}`; | ||
| + | </ | ||
| + | |||
| + | En resumen, la interpolación de cadenas nos permite crear fácilmente cadenas compuestas por varios elementos de forma sencilla y mucho más legible que usando concatenaciones. Ya verás que cuando empieces a usarla... ¡te costará volver a concatenar cadenas! | ||
| + | ===== Desestructuración en arrays ===== | ||
| + | |||
| + | La desestructuración (en inglés // | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | La desestructuración está basada en el // | ||
| + | </ | ||
| + | |||
| + | Veamos un ejemplo de su uso: | ||
| + | |||
| + | <code javascript> | ||
| + | var [a,b] = [1,2]; | ||
| + | </ | ||
| + | |||
| + | Este código deja el valor '' | ||
| + | |||
| + | Sin la desestructuración, | ||
| + | |||
| + | <code javascript> | ||
| + | var data = [4, 8, 15, 16, 23, 42]; | ||
| + | |||
| + | // Sin desestructuración | ||
| + | var first = data[0]; | ||
| + | var second = data[1]; | ||
| + | var fourth = data[3]; | ||
| + | |||
| + | // Con desestructuración | ||
| + | var [first, second,, | ||
| + | </ | ||
| + | |||
| + | Observa el código de la última línea en el ejemplo anterior. Las dos comas seguidas. Eso permite saltarse un elemento del array que estamos desestructurando. Es decir, '' | ||
| + | |||
| + | La desestructuración no requiere que haya constantes en el lado derecho de la asignación, | ||
| + | |||
| + | <code javascript> | ||
| + | var x=10; | ||
| + | var y=20; | ||
| + | var z=30; | ||
| + | var [x,y,z] = [z,x,20]; | ||
| + | </ | ||
| + | |||
| + | Al final de este código el valor de: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | Pregunta: ¿Cómo intercambiarías el valor de dos variables usando la desestructuración? | ||
| + | |||
| + | ==== Desestructuración en valores de retorno ==== | ||
| + | |||
| + | Si una función devuelve un array, se puede usar la desestructuración para obtener todos o aquellos elementos del array que nos interesen: | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function() {return [1,2,3];} | ||
| + | var [a,,b] = foo(); | ||
| + | </ | ||
| + | |||
| + | Al final de este código, '' | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | La desestructuración es segura. Si intentamos desestructurar más elementos de los que hay en el array, los que no existan devuelven '' | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== DEMO: Desestructuración en arrays ===== | ||
| + | |||
| + | La desestructuración se basa en //pattern matching// | ||
| + | |||
| + | <code javascript> | ||
| + | var arr = [10, 20]; | ||
| + | |||
| + | // Lo que nos permite la desestructuración es declarar variables de la siguiente manera | ||
| + | var [a, b] = arr; | ||
| + | |||
| + | a; // -> 10 | ||
| + | b: // -> 20 | ||
| + | |||
| + | var [c,d] = [30, 40]; | ||
| + | |||
| + | c; // -> 30 | ||
| + | d; // -> 40 | ||
| + | </ | ||
| + | |||
| + | Esta característica también nos permite intercambiar valores de variables en una única instrucción: | ||
| + | |||
| + | <code javascript> | ||
| + | [a, c] = [c, a]; | ||
| + | </ | ||
| + | |||
| + | Incluso podemos decidir qué valores recoger. En el siguiente ejemplo cogeremos el primer y último elementos: | ||
| + | |||
| + | <code javascript> | ||
| + | arr = [10, 20, 30, 40]; | ||
| + | |||
| + | var [i,,,f] = arr; | ||
| + | |||
| + | i; // -> 10 | ||
| + | f; // -> 40 | ||
| + | </ | ||
| + | |||
| + | Incluso podemos hacerlo con arrays más pequeños de lo esperado y no nos dará error: | ||
| + | |||
| + | <code javascript> | ||
| + | var [e,,,f] = [10]; | ||
| + | |||
| + | e; // -> 10 | ||
| + | f; // -> ' | ||
| + | </ | ||
| + | ===== Desestructuración en objetos ===== | ||
| + | |||
| + | La desestructuración también funciona en objetos. Es decir, se puede desestructurar un objeto y asignar todas o algunas de sus propiedades a variables simples: | ||
| + | |||
| + | <code javascript> | ||
| + | var obj = {a: 10, b: 42}; | ||
| + | // Sin desestructuración | ||
| + | var x = obj.a; | ||
| + | var y = obj.b; | ||
| + | // Usando desestructuración | ||
| + | var {a: x, b: y} = obj; | ||
| + | </ | ||
| + | |||
| + | Al finalizar el código el valor de '' | ||
| + | |||
| + | Podemos desestructurar parcialmente un objeto, no necesitamos desestructurar todas sus propiedades: | ||
| + | |||
| + | <code javascript> | ||
| + | var {b: x} = {a: 10, b: 42} | ||
| + | </ | ||
| + | |||
| + | Al finalizar el código la variable '' | ||
| + | |||
| + | Por supuesto, puede combinarse la desestructuración de arrays y objetos: | ||
| + | |||
| + | <code javascript> | ||
| + | var data = {a:10, b:[1,2,3, {c: 40, d: 50}]}; | ||
| + | var {b: [,x]} = data; | ||
| + | </ | ||
| + | |||
| + | Al finalizar este código el valor de '' | ||
| + | |||
| + | ==== Desestructuración en parámetros ==== | ||
| + | |||
| + | La gestión de parámetros opcionales en las funciones en JavaScript siempre ha sido problemática. Cierto es que usando '' | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function(params) { | ||
| + | var uri = params.uri; | ||
| + | var method = params.method || ' | ||
| + | var contentType = params.contentType || ' | ||
| + | // Hacer la petición a la uri indicada con el método y content-type indicados | ||
| + | } | ||
| + | // Uso de la función: | ||
| + | foo({uri: ' | ||
| + | foo({uri: ' | ||
| + | </ | ||
| + | |||
| + | El principal problema para alguien que quiera llamar a '' | ||
| + | |||
| + | No hay más solución que leerse todo el código fuente de la función. Solo así podemos ver que la función '' | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function({uri: | ||
| + | // En este punto las variables uri, method y contentType ya existen gracias a la desestructuración | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Para quien llame a '' | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function({uri, | ||
| + | // En este punto las variables uri, method y contentType ya existen gracias a la desestructuración | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | Recuerda que en ECMAScript 2015 si usamos notación de objeto y una propiedad "'' | ||
| + | </ | ||
| + | |||
| + | Incluso podemos ir un paso más allá y **dar valores por defecto a las propiedades no pasadas**: | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function({uri, | ||
| + | // En este punto las variables uri, method y ctype ya existen gracias a la desestructuración | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | En este caso si el llamante no especifica el valor de las propiedades '' | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | Observa que cuando usamos los valores por defecto, aunque la variable resultado de la desestructuración se llame igual que la propiedad del objeto, debemos especificar ambos (caso de '' | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== DEMO: Desestructuración en objetos ===== | ||
| + | |||
| + | <code javascript> | ||
| + | var obj = { | ||
| + | a: 10, | ||
| + | b: 42 | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | Sin desestructuración: | ||
| + | |||
| + | <code javascript> | ||
| + | var x = obj.a; | ||
| + | var y = obj.b; | ||
| + | </ | ||
| + | |||
| + | Con la desestructuración: | ||
| + | |||
| + | <code javascript> | ||
| + | var {a: x, b: y} = obj; | ||
| + | </ | ||
| + | |||
| + | Como vemos, ponemos primero el nombre de la propiedad que queremos desestructurar y luego la variable que recibirá el valor de la desestructuración. | ||
| + | |||
| + | <code javascript> | ||
| + | console.log(x, | ||
| + | </ | ||
| + | |||
| + | Podemos desestructurar parte del objeto: | ||
| + | |||
| + | <code javascript> | ||
| + | var { b: z } = obj; | ||
| + | |||
| + | console.log(z); | ||
| + | </ | ||
| + | |||
| + | Desestructurando propiedades que no existen: | ||
| + | |||
| + | <code javascript> | ||
| + | var {a: x, _b: y} = obj; | ||
| + | |||
| + | console.log(x, | ||
| + | </ | ||
| + | |||
| + | En resumen, la desestructuración nos permite extraer elementos de un array o valores de propiedades de un objeto a variables simples. Y extraer todos y algunos elementos. Si no existen las variables a desestructurar, | ||
| + | ===== DEMO: Desestructuración en parámetros ===== | ||
| + | |||
| + | Es muy habitual en JavaScript hacer funciones que acepten un objeto como parámetro. En la firma de la función no sabemos qué propiedades tendrá ese objeto: | ||
| + | |||
| + | <code javascript> | ||
| + | var f = function(params) { | ||
| + | console.log(params.url); | ||
| + | } | ||
| + | |||
| + | f({url: " | ||
| + | </ | ||
| + | |||
| + | Con la desestructuración: | ||
| + | |||
| + | <code javascript> | ||
| + | var f = function({url: | ||
| + | console.log(x); | ||
| + | } | ||
| + | |||
| + | f({url: " | ||
| + | </ | ||
| + | |||
| + | Esto permite tener parámetros nombrados dentro de un objeto y ayudar a la legibilidad del código. | ||
| + | ===== Operador spread ===== | ||
| + | |||
| + | El operador **spread** permite que en situaciones en las que se espera un valor, aparezcan varios valores. Es un operador muy potente, y la mejor manera de entenderlo es verlo en acción. | ||
| + | |||
| + | Empecemos viéndolo en combinación con la desestructuración: | ||
| + | |||
| + | <code javascript> | ||
| + | var [a,b,...c] = [10, 20, 30, 40, 50]; | ||
| + | </ | ||
| + | |||
| + | El operador **spread** son los tres puntos ('' | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | Cuando el operador **spread** se usa de ese modo, tan solo puede aparecer una vez y en el último lugar. | ||
| + | </ | ||
| + | |||
| + | Otro uso interesante del operador es llamar a funciones con N parámetros a partir de un array con N valores: | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function(a, | ||
| + | console.log(a, | ||
| + | } | ||
| + | foo(...[10, | ||
| + | </ | ||
| + | |||
| + | Observa cómo llamamos a la función '' | ||
| + | |||
| + | Se pueden combinar varios operadores spread llamando a una función, y eso se puede combinar con parámetros normales. La flexibilidad es total: | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function(a, | ||
| + | } | ||
| + | foo(10, ...[20, 30], 40, ...[50]); | ||
| + | </ | ||
| + | |||
| + | En este código... | ||
| + | |||
| + | * El valor del parámetro '' | ||
| + | * El valor del parámetro '' | ||
| + | * El valor del parámetro '' | ||
| + | * El valor del parámetro '' | ||
| + | * El valor del parámetro '' | ||
| + | |||
| + | ==== Parámetros rest ==== | ||
| + | |||
| + | El operador //spread// se puede aplicar al último parámetro de una función. Cuando hacemos esto decimos que este parámetro es un " | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function(a, | ||
| + | foo(10, 20, 30); // c vale [30] | ||
| + | foo(10, 20, 30, 40); // c vale [30, 40] | ||
| + | foo(10, | ||
| + | </ | ||
| + | |||
| + | Quizá te preguntes qué aportan los parámetros //rest//, existiendo '' | ||
| + | |||
| + | ===== DEMO: Operador spread ===== | ||
| + | |||
| + | Desestructuración normal: | ||
| + | |||
| + | <code javascript> | ||
| + | var arr = [1, | ||
| + | |||
| + | var [x,,,y] = arr; | ||
| + | |||
| + | console.log(x, | ||
| + | </ | ||
| + | |||
| + | Aplicando el operador //spread// ('' | ||
| + | |||
| + | <code javascript> | ||
| + | var arr = [1, | ||
| + | |||
| + | var [x,,, | ||
| + | |||
| + | console.log(x, | ||
| + | </ | ||
| + | |||
| + | El operador //spread// permite que varios valores se obtengan en un nuevo array. | ||
| + | |||
| + | Este operador también nos permite combinar fácilmente arrays: | ||
| + | |||
| + | <code javascript> | ||
| + | var uno = [1, 2, 5, 6]; | ||
| + | |||
| + | // Queremos que el segundo array tenga unos elementos y el anterior array: | ||
| + | var dos = [100, 200, ...uno, 300]; | ||
| + | |||
| + | dos;// Array [ 100, 200, 1, 2, 5, 6, 300 ] | ||
| + | </ | ||
| + | |||
| + | Otro de los usos de este operador es para las funciones sin necesidad de usar '' | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function(a, b, c, d, e) { | ||
| + | console.log(a, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Uso: | ||
| + | <code javascript> | ||
| + | var arr = [1, | ||
| + | |||
| + | // Imaginemos que queremos asociar cada uno de esos valores del array | ||
| + | // a los distintos argumentos de la función ' | ||
| + | foo(...arr); | ||
| + | </ | ||
| + | |||
| + | Si tuviéramos menos elementos: | ||
| + | |||
| + | <code javascript> | ||
| + | var arr = [1, | ||
| + | |||
| + | // El resto de parámetros de la función se los podríamos | ||
| + | // pasar así: | ||
| + | foo(...arr, 100, 200); | ||
| + | </ | ||
| + | |||
| + | También es posible hacer esto: | ||
| + | |||
| + | <code javascript> | ||
| + | var arr = [1, | ||
| + | var arr2 = [200, 300]; | ||
| + | |||
| + | |||
| + | foo(...arr, ...arr2); | ||
| + | |||
| + | También podemos hacer: | ||
| + | |||
| + | foo(...arr, ...[10], ...[30]); | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== DEMO: Parámetros rest ===== | ||
| + | |||
| + | Llamamos parámetros //rest// a que podemos aplicar el operador //spread// como último parámetro de una función y este último parámetro será un array que contendrá todos los parámetros no nombrados de la función. | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function(a, b, ...c) { | ||
| + | console.log(a); | ||
| + | console.log(b); | ||
| + | console.log(c); | ||
| + | } | ||
| + | |||
| + | foo(10, 20, 30); | ||
| + | // 10 | ||
| + | // 20 | ||
| + | // Array [ 30 ] | ||
| + | |||
| + | foo(10, 20, 30, 40, 50, 60); | ||
| + | // 10 | ||
| + | // 20 | ||
| + | // Array [ 30, 40, 50, 60 ] | ||
| + | </ | ||
| + | |||
| + | Los parámetros //rest// no fallan, por ejemplo, veamos qué pasa si le pasamos a la función todos los argumentos menos los //rest//: | ||
| + | |||
| + | <code javascript> | ||
| + | foo(10, 20); | ||
| + | |||
| + | // 10 | ||
| + | // 20 | ||
| + | // Array [ ] | ||
| + | </ | ||
| + | |||
| + | Vamos a ver diferencias con '' | ||
| + | |||
| + | <code javascript> | ||
| + | var foo = function(a, b, ...c) { | ||
| + | console.log(a); | ||
| + | console.log(b); | ||
| + | console.log(c); | ||
| + | console.log(arguments); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Usamos: | ||
| + | |||
| + | <code javascript> | ||
| + | foo(10, 20, 30, 40); | ||
| + | // 10 | ||
| + | // 20 | ||
| + | // Array [ 30, 40 ] | ||
| + | // Arguments { , 7 more... } | ||
| + | </ | ||
| + | |||
| + | '' | ||
informatica/programacion/cursos/programacion_avanzada_javascript/desestructuracion.1729153472.txt.gz · Última modificación: por tempwin
