informatica:programacion:cursos:programacion_avanzada_javascript:otras_caracteristicas_ecmascript
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| informatica:programacion:cursos:programacion_avanzada_javascript:otras_caracteristicas_ecmascript [2024/10/29 16:15] – [Cortocircuito de expresiones] tempwin | informatica:programacion:cursos:programacion_avanzada_javascript:otras_caracteristicas_ecmascript [2024/10/30 13:13] (actual) – [Paréntesis obligatorios] tempwin | ||
|---|---|---|---|
| Línea 185: | Línea 185: | ||
| El resultado es que **se produce un error**: '' | El resultado es que **se produce un error**: '' | ||
| - | <WRAP center round todo 60%> | + | {{ : |
| - | El error que se produce | + | |
| - | </ | + | |
| El motivo es que, al combinar este tipo de operadores, hagas lo que hagas con la precedencia no puedes evitar que la interpretación que hace el programador de lo que está escribiendo entre en conflicto con lo que el diseñador del lenguaje haya decidido. Por ejemplo, en el fragmento anterior, eso se puede interpretar como: | El motivo es que, al combinar este tipo de operadores, hagas lo que hagas con la precedencia no puedes evitar que la interpretación que hace el programador de lo que está escribiendo entre en conflicto con lo que el diseñador del lenguaje haya decidido. Por ejemplo, en el fragmento anterior, eso se puede interpretar como: | ||
| Línea 210: | Línea 208: | ||
| ===== El operador de encadenamiento opcional: evitando errores por nulos ===== | ===== El operador de encadenamiento opcional: evitando errores por nulos ===== | ||
| - | El operador de encadenamiento opcional, ?. apareció con ECMAScript 2020 y nos permite simplificar enormemente las expresiones con propiedades o arrays que podrían tener valores nulos. | + | El operador de encadenamiento opcional, |
| Un caso habitual es el siguiente: estamos accediendo a un servicio que nos devuelve información de objetos que necesitamos para nuestra aplicación. Estos objetos pueden tener a su vez varios subobjetos a los que necesitamos acceder para hacer cosas, por ejemplo: | Un caso habitual es el siguiente: estamos accediendo a un servicio que nos devuelve información de objetos que necesitamos para nuestra aplicación. Estos objetos pueden tener a su vez varios subobjetos a los que necesitamos acceder para hacer cosas, por ejemplo: | ||
| + | <code javascript> | ||
| if (usuario.direccion.planta.length > 0) { | if (usuario.direccion.planta.length > 0) { | ||
| //lo que sea... | //lo que sea... | ||
| } | } | ||
| + | </ | ||
| - | El problema de lo anterior es que es posible que el usuario no tenga dirección, y si la tiene quizá no tiene el campo de la planta en la que vive (porque es una casa unifamiliar, | + | El problema de lo anterior es que es posible que el usuario no tenga dirección, y si la tiene quizá no tiene el campo de la planta en la que vive (porque es una casa unifamiliar, |
| + | <code javascript> | ||
| if (usuario && usuario.direccion && usuario.direccion.planta) { | if (usuario && usuario.direccion && usuario.direccion.planta) { | ||
| if (usuario.direccion.planta.length > 0) { | if (usuario.direccion.planta.length > 0) { | ||
| Línea 225: | Línea 226: | ||
| } | } | ||
| } | } | ||
| + | </ | ||
| Es decir, antes de poder utilizar nuestra expresión original debemos comprobar que todos los elementos de la cadena de propiedades existen (no son nulos), para asegurarnos de que no se produce un error. | Es decir, antes de poder utilizar nuestra expresión original debemos comprobar que todos los elementos de la cadena de propiedades existen (no son nulos), para asegurarnos de que no se produce un error. | ||
| - | | + | <WRAP center round tip 60%> |
| + | Obviamente sólo es necesario comprobar aquellos que puedan estar nulos. Por ejemplo, su el usuario siempre va a existir como resultado de la llamada al servicio (o sea, el servicio no nos va a devolver nunca un nulo), la primera comprobación ('' | ||
| + | </ | ||
| - | Lo anterior funciona porque el operador AND (&& | + | Lo anterior funciona porque el operador AND ('' |
| - | Este tipo de expresiones es muy habitual verlas por ahí y funcionan bien, pero son tediosas de escribir, largas y no contribuyen precisamente a la claridad del código. | + | Este tipo de expresiones es muy habitual verlas por ahí y funcionan bien, pero **son tediosas de escribir, largas y no contribuyen precisamente a la claridad del código**. |
| Por suerte, ECMAScript nos proporciona un elemento específico para facilitarnos la vida: el operador de encadenamiento opcional: ?.. Gracias a él podemos escribir esto: | Por suerte, ECMAScript nos proporciona un elemento específico para facilitarnos la vida: el operador de encadenamiento opcional: ?.. Gracias a él podemos escribir esto: | ||
| + | <code javascript> | ||
| if (usuario? | if (usuario? | ||
| //lo que sea... | //lo que sea... | ||
| } | } | ||
| + | </ | ||
| - | Es decir, al ponerlo delante de una propiedad, ésta sólo se evalúa si el objeto precedente no es nulo ni undefined (o no es " | + | Es decir, al ponerlo delante de una propiedad, ésta **sólo se evalúa si el objeto precedente no es nulo ni '' |
| - | Lo que se obtiene en caso de que algún punto de la cadena sea nulo o no definido es un valor no definido, o sea undefined. | + | Lo que se obtiene en caso de que algún punto de la cadena sea nulo o no definido es **un valor no definido**, o sea '' |
| - | Esto es equivalente a usar todos aquellos && de antes, pero mucho más claro de leer y sobre todo de escribir. | + | Esto es equivalente a usar todos aquellos |
| - | | + | <WRAP center round important 60%> |
| + | MUY IMPORTANTE: el primer objeto de la cadena debe existir y estar definido, ya que el operador necesita al menos un objeto " | ||
| + | </ | ||
| - | Llamadas a funciones | + | ==== Llamadas a funciones |
| - | Pero este operador sirve para más cosas que simplemente encadenar propiedades de objetos. También es posible utilizarlo para hacer llamadas a funciones, sólo si la función está definida. Por ejemplo: | + | Pero este operador sirve para más cosas que simplemente encadenar propiedades de objetos. También es posible utilizarlo para hacer **llamadas a funciones, sólo si la función está definida**. Por ejemplo: |
| + | <code javascript> | ||
| var res = usuario? | var res = usuario? | ||
| + | </ | ||
| - | Esta sintaxis tan rara, ?.() lo que quiere decir es que, si está definida la función, llámala, y si no lo está, devuelve un undefined. De este modo podemos crear interfaces que tengan miembros opcionales, que sólo se implementan según ciertas condiciones, | + | Esta sintaxis tan rara, '' |
| - | Es importante señalar que si el supuesto método existe pero no es un método, se producirá un error de tipos. Es decir, lo anterior funciona si el miembro que queremos llamar no existe. Pero, en nuestro ejemplo, si usuario.hazAlgo existe y es otra cosa que no es una función (por ejemplo un array o una simple propiedad) se producirá un TypeError. Esto es una buena política porque sino podrían darse otros errores diferentes. De este modo tenemos que ser conscientes que vamos a llamar a una posible función. | + | Es importante señalar que si el supuesto método existe pero no es un método, se producirá un error de tipos. Es decir, lo anterior funciona si el miembro que queremos llamar no existe. Pero, en nuestro ejemplo, si '' |
| - | Cortocircuito de expresiones | + | |
| + | ==== Cortocircuito de expresiones | ||
| Este operador también incluye cortocircuito de expresiones. Es decir, que en cuanto se encuentra un eslabón de la cadena que es nulo o no definido, no sigue evaluando los demás. Así, por ejemplo: | Este operador también incluye cortocircuito de expresiones. Es decir, que en cuanto se encuentra un eslabón de la cadena que es nulo o no definido, no sigue evaluando los demás. Así, por ejemplo: | ||
| + | <code javascript> | ||
| var n = 0; | var n = 0; | ||
| var res = usuario? | var res = usuario? | ||
| + | </ | ||
| - | ...si el usuario o si la función hacerAlgo no existe y por tanto no se ejecuta, la variable n tampoco aumenta de valor ya que se detiene la evaluación de la expresión posterior a ella. | + | ...si el usuario o si la función |
| - | Acceso a arrays | + | |
| - | En JavaScript una alternativa | + | ==== Acceso |
| + | En JavaScript una alternativa a la sintaxis '' | ||
| + | |||
| + | <code javascript> | ||
| var color = usuario.ajustes[' | var color = usuario.ajustes[' | ||
| + | </ | ||
| que es equivalente a: | que es equivalente a: | ||
| + | <code javascript> | ||
| var color = usuario.ajustes.color; | var color = usuario.ajustes.color; | ||
| + | </ | ||
| La ventaja de la primera sintaxis es que nos permite decidir el nombre de la propiedad dinámicamente, | La ventaja de la primera sintaxis es que nos permite decidir el nombre de la propiedad dinámicamente, | ||
| + | <code javascript> | ||
| var nomAjuste = obtenerNombreAjusteColor(); | var nomAjuste = obtenerNombreAjusteColor(); | ||
| var color = usuario.ajustes.[nomAjuste]; | var color = usuario.ajustes.[nomAjuste]; | ||
| + | </ | ||
| cosa que no podríamos hacer con la sintaxis habitual del punto. | cosa que no podríamos hacer con la sintaxis habitual del punto. | ||
| - | En este caso, si la propiedad es nula o no está definida JavaScript devuelve un error. O sea, en este ejemplo si el servicio nos devuelve un null en la propiedad ajustes o si directamente no la define, se produciría un error. | + | En este caso, si la propiedad es nula o no está definida JavaScript devuelve un error. O sea, en este ejemplo si el servicio nos devuelve un '' |
| - | Para facilitar este caso, una tercera sintaxis de este operador nos permite acceder al contenido de arrays o colecciones aunque sean nulas o no estén definidas: | + | Para facilitar este caso, una tercera sintaxis de este operador nos permite |
| + | <code javascript> | ||
| var color = usuario? | var color = usuario? | ||
| + | </ | ||
| - | En este caso está intentando acceder a las propiedades del objeto ajustes por su nombre. | + | En este caso está intentando acceder a las propiedades del objeto |
| - | Fíjate además que, por el cortocircuito de expresiones, | + | Fíjate además que, por el cortocircuito de expresiones, |
| Nos vale también para arrays normales y corrientes accedidas mediante índice: | Nos vale también para arrays normales y corrientes accedidas mediante índice: | ||
| + | <code javascript> | ||
| var color = usuario? | var color = usuario? | ||
| + | </ | ||
| - | De este modo si ajustes no está definido o es nulo no se producirá un error, como sí ocurriría sin este operador. | + | De este modo si '' |
| - | Devolver algo diferente a no definido | + | |
| + | ==== Devolver algo diferente a no definido | ||
| Finalmente, podemos combinar ese nuevo operador con el operador de unión " | Finalmente, podemos combinar ese nuevo operador con el operador de unión " | ||
| + | <code javascript> | ||
| var color = usuario? | var color = usuario? | ||
| + | </ | ||
| que en caso de no estar definido devolvería un color por defecto (el color blanco). | que en caso de no estar definido devolvería un color por defecto (el color blanco). | ||
| - | En resumen | ||
| - | El operador ?. es muy útil para escribir expresiones concisas y legibles sin arriesgarnos a que un valor nulo o no definido provoque un error en nuestro código. Su uso es extremadamente sencillo y sólo hay que conocer los pequeños detalles asociados que se explican en esta lección. | + | ==== En resumen ==== |
| + | |||
| + | El operador | ||
| - | El soporte de este operador es total en los navegadores evergreen, o sea, en todos los actuales (Chrome, Firefox, Opera, Safari, Brave...), así que podemos usarlo sin miedo salvo que tengamos que dar soporte a versiones antiguas o a Internet Explorer por algún motivo. | + | El soporte de este operador es total en los navegadores |
informatica/programacion/cursos/programacion_avanzada_javascript/otras_caracteristicas_ecmascript.1730214936.txt.gz · Última modificación: por tempwin
