Guía de JavaScript Parte 6: Excepciones, punto y coma, plantillas literales

Los temas en esta parte de la traducción del tutorial de JavaScript serán el manejo de excepciones, las características de punto y coma automáticas y los literales de plantilla.

Parte 1: primer programa, características del lenguaje, estándares
Parte 2: estilo de código y estructura del programa
Parte 3: variables, tipos de datos, expresiones, objetos.
Parte 4: funciones
Parte 5: matrices y bucles
Parte 6: excepciones, punto y coma, literales comodín
Parte 7: modo estricto, esta palabra clave, eventos, módulos, cálculos matemáticos
Parte 8: Descripción general de las características de ES6
Parte 9: Descripción general de los estándares ES7, ES8 y ES9



Manejo de excepciones


Cuando ocurre un problema durante la ejecución del código, se expresa como una excepción en JavaScript. Si no toma medidas para manejar las excepciones, cuando ocurren, el programa se detiene y se muestra un mensaje de error en la consola.

Considere el siguiente fragmento de código.

let obj = {value: 'message text'} let notObj let fn = (a) => a.value console.log(fn(obj)) //message text console.log('Before') //Before console.log(fn(notObj)) //,    console.log('After') 

Aquí tenemos una función que planeamos usar para procesar objetos que tienen la propiedad de value . Ella devuelve esta propiedad. Si utiliza esta función para su propósito previsto, es decir, para transferirle un objeto con el que está diseñado para trabajar, no se generarán errores cuando se ejecute. Pero si le pasa algo inapropiado, en nuestro caso, una variable declarada pero no inicializada, entonces se produce un error cuando intenta acceder a la propiedad de valor de valor undefined . Aparecerá un mensaje de error en la consola, la ejecución del programa se detendrá.

Esto es lo que parece cuando ejecuta este código en Node.js.


Excepción de TypeError en Node.js

Si ocurre algo como esto en el código JS de una página web, se enviará un mensaje similar a la consola del navegador. Si esto sucede en un programa real, por ejemplo, en el código del servidor web, este comportamiento es extremadamente indeseable. Sería bueno tener un mecanismo que permita, sin detener el programa, detectar el error y luego tomar medidas para corregirlo. Tal mecanismo existe en JavaScript; está representado por la construcción try...catch .

▍construcción intente ... atrapar


La construcción try...catch te permite capturar y manejar excepciones. Es decir, incluye un bloque de try , que incluye código que puede causar un error, y un catch , en el que el control se transfiere cuando se produce un error. try bloques de try no incluyen absolutamente todo el código del programa. Las partes que pueden causar errores de tiempo de ejecución se colocan allí. Por ejemplo, llamadas a funciones que tienen que trabajar con ciertos datos recibidos de fuentes externas. Si la estructura de dichos datos es diferente de lo que la función espera, puede ocurrir un error. Así es como se ve el diagrama de diseño try...catch .

 try { // ,     } catch (e) { //  } 

Si el código se ejecuta sin errores, el catch (controlador de excepciones) no se ejecuta. Si se produce un error, el objeto de error se transfiere allí y se toman algunas medidas para combatir este error.

Aplicamos esta construcción en nuestro ejemplo, protegiendo con su ayuda secciones peligrosas del programa, aquellas en las que fn() llama a la función fn() .

 let obj = {value: 'message text'} let notObj let fn = (a) => a.value try {   console.log(fn(obj)) } catch (e) {   console.log(e.message) } console.log('Before') //Before try {   console.log(fn(notObj)) } catch (e) {   console.log(e.message) //Cannot read property 'value' of undefined } console.log('After') //After 

Veamos los resultados de ejecutar este código en Node.js.


Manejo de errores en Node.js

Como puede ver, si compara este ejemplo con el anterior, ahora se ejecuta todo el código, y el que se encuentra antes de la línea problemática, y el que se encuentra después. "Procesamos" el error simplemente imprimiendo en la consola los valores de la propiedad del message del objeto Error . El manejo del error que ocurrió en el código realmente utilizado depende del error.

Discutimos el bloque try...catch arriba, pero, de hecho, esta construcción incluye otro bloque, finally .

▍ finalmente bloquear


El finally bloque contiene código que se ejecuta independientemente de si se produjo o no un error en el código que se ejecuta en el bloque de try . Así es como se ve.

 try { //  } catch (e) { //  } finally { //  } 

El finally bloque también se puede usar si el bloque try...catch...finally no tiene un catch . En este enfoque, se usa de la misma manera que en la construcción con el catch , por ejemplo, para liberar recursos ocupados en el bloque try .

▍ Bloques de prueba anidados


Los bloques de prueba se pueden anidar juntos. En este caso, la excepción se maneja en el catch más cercano.

 try { //  try {   //   } finally {   // -  } } catch (e) { } 

En este caso, si se produce una excepción en el bloque try interno, se procesará en el catch externo.

▍ Excepción autogenerada


Las excepciones pueden ser lanzadas por usted mismo utilizando la instrucción throw . Así es como se ve.

 throw value 

Después de ejecutar esta instrucción, el control se transfiere al catch más cercano, o si no se puede encontrar dicho bloque, el programa se detiene. El valor de excepción puede ser cualquier cosa. Por ejemplo, un objeto de error definido por el usuario.

Sobre punto y coma


El uso de punto y coma en JavaScript es opcional. Algunos programadores lo hacen sin ellos, confiando en un sistema de disposición automática para ellos y colocándolos solo donde sea absolutamente necesario. Algunas personas prefieren colocarlos siempre que sea posible. El autor de este material se refiere a la categoría de programadores que quieren prescindir de punto y coma. Él dice que decidió prescindir de ellos en el otoño de 2017 al configurar Prettier para eliminarlos donde sea que pueda prescindir de su inserción explícita. En su opinión, el código sin punto y coma parece más natural y más fácil de leer.

Quizás podamos decir que la comunidad de desarrolladores de JS está dividida, en relación con los puntos y comas, en dos campos. Al mismo tiempo, también hay guías de estilo JavaScript que prescriben puntos y comas explícitos, y guías que recomiendan prescindir de ellas.

Todo esto es posible debido al hecho de que JavaScript tiene un sistema para punto y coma automático (Inserción automática de punto y coma, ASI). Sin embargo, el hecho de que en el código JS, en muchas situaciones, puede prescindir de estos caracteres, y el hecho de que los puntos y comas se colocan automáticamente al preparar el código para la ejecución, no significa que el programador no necesite conocer las reglas por las cuales esto sucede. La ignorancia de estas reglas conduce a errores.

▍ Reglas para punto y coma automático


El analizador de JavaScript agrega automáticamente punto y coma al analizar el texto del programa en las siguientes situaciones:

  1. Cuando la siguiente línea comienza con un código que interrumpe el código actual (el código de un determinado comando puede estar ubicado en varias líneas).
  2. Cuando la siguiente línea comienza con el carácter } , que cierra el bloque actual.
  3. Cuando se detecta el final del archivo con el código del programa.
  4. En la línea con el comando de return .
  5. En la línea con el comando break .
  6. En la línea con el comando de throw .
  7. En la línea con el comando continue .

▍ Ejemplos de código que no funciona como se esperaba


Aquí hay algunos ejemplos que ilustran las reglas anteriores. Por ejemplo, ¿qué crees que se mostrará como resultado de la ejecución del siguiente fragmento de código?

 const hey = 'hey' const you = 'hey' const heyYou = hey + ' ' + you ['h', 'e', 'y'].forEach((letter) => console.log(letter)) 

Cuando intente ejecutar este código, se generará un error Uncaught TypeError: Cannot read property 'forEach' of undefined sistema Uncaught TypeError: Cannot read property 'forEach' of undefined , según la regla No. 1, intenta interpretar el código de la siguiente manera.

 const hey = 'hey'; const you = 'hey'; const heyYou = hey + ' ' + you['h', 'e', 'y'].forEach((letter) => console.log(letter)) 

El problema se puede resolver poniendo un punto y coma después de la penúltima línea del primer ejemplo.

Aquí hay otra pieza de código.

 (1 + 2).toString() 

El resultado de su ejecución será la salida de la cadena "3" . Pero, ¿qué sucede si algo como esto aparece en el siguiente fragmento de código?

 const a = 1 const b = 2 const c = a + b (a + b).toString() 

En esta situación, aparecerá un error TypeError: b is not a function ya que el código anterior se interpretará de la siguiente manera.

 const a = 1 const b = 2 const c = a + b(a + b).toString() 

Veamos ahora un ejemplo basado en la regla 4.

 (() => { return {   color: 'white' } })() 

Puede pensar que este IIFE devolverá un objeto que contiene la propiedad de color , pero de hecho no lo es. En cambio, la función volverá undefined porque el sistema agrega un punto y coma después del comando de return .

Para resolver un problema similar, la llave de apertura del objeto literal debe colocarse en la misma línea que el comando de return .

 (() => { return {   color: 'white' } })() 

Si observa el siguiente fragmento de código, puede pensar que mostrará 0 en el cuadro de mensaje.

 1 + 1 -1 + 1 === 0 ? alert(0) : alert(2) 

Pero genera 2, porque, de acuerdo con la regla No. 1, este código se representa de la siguiente manera.

 1 + 1 -1 + 1 === 0 ? alert(0) : alert(2) 

Debe tener cuidado al usar punto y coma en JavaScript. Puedes conocer tanto a los ardientes partidarios del punto y coma como a sus oponentes. De hecho, al decidir si se necesitan punto y coma en su código, puede confiar en el hecho de que JS admite su sustitución automática, pero todos deben decidir por sí mismos si son necesarios en su código o no. Lo principal es aplicar el enfoque elegido de manera consistente y razonable. Con respecto a la ubicación de los puntos y comas y la estructura del código, podemos recomendar las siguientes reglas:

  • Usando el comando de return , organice lo que debe regresar de la función en la misma línea que el comando. Lo mismo ocurre con el break , throw , continue comandos.
  • Preste especial atención a las situaciones en las que una nueva línea de código comienza con un paréntesis, ya que esta línea puede combinarse automáticamente con la anterior y presentarse por el sistema como un intento de llamar a una función o un intento de acceder a un elemento de matriz.

En general, se puede decir que si coloca los puntos y comas usted mismo o si confía en su ubicación automática, pruebe el código para asegurarse de que funciona exactamente como se esperaba.

Comillas y literales comodín


Hablemos de las características del uso de citas en JavaScript. A saber, estamos hablando de los siguientes tipos de citas permitidas en los programas JS:

  • Comillas simples
  • Comillas dobles.
  • Cotizaciones posteriores.

Las comillas simples y dobles, en general, pueden considerarse lo mismo.

 const test = 'test' const bike = "bike" 

Prácticamente no hay diferencia entre ellos. Quizás la única diferencia notable es que en las cadenas entre comillas simples, debe escapar del carácter de una comilla simple, y en las cadenas entre comillas dobles, el carácter es doble.

 const test = 'test' const test = 'te\'st' const test = 'te"st' const test = "te\"st" const test = "te'st" 

En diferentes guías de estilo, puede encontrar una recomendación para usar comillas simples y una recomendación para usar comillas dobles. El autor de este material dice que en el código JS se esfuerza por utilizar exclusivamente comillas simples, utilizando comillas dobles solo en el código HTML.

Los backticks aparecieron en JavaScript con el lanzamiento del estándar ES6 en 2015. Ellos, entre otras características nuevas, permiten describir convenientemente cadenas de varias líneas. Tales cadenas también se pueden especificar utilizando comillas regulares, utilizando la secuencia de escape \n . Se ve así.

 const multilineString = 'A string\non multiple lines' 

Las comillas invertidas (generalmente el botón para ingresarlas se encuentra a la izquierda de la tecla numérica 1 en el teclado) no tienen \n .

 const multilineString = `A string on multiple lines` 

Pero las posibilidades de los backquotes no se limitan a esto. Entonces, si una cadena se describe utilizando comillas inversas, es posible sustituir valores del cálculo de expresiones JS en ella utilizando la construcción ${} .

 const multilineString = `A string on ${1+1} lines` 

Tales cadenas se llaman literales de plantilla.

Los literales de plantilla tienen las siguientes características:

  • Admiten texto de varias líneas.
  • Permiten interpolar cadenas; pueden usarse expresiones incorporadas en ellas.
  • Le permiten trabajar con plantillas etiquetadas, lo que le permite crear sus propios idiomas específicos de dominio (DSL, lenguaje específico de dominio).

Hablemos de estas características.

▍ Texto multilínea


Al configurar textos de varias líneas con comillas inversas, debe recordar que los espacios en dichos textos son tan importantes como otros caracteres. Por ejemplo, considere el siguiente texto de varias líneas.

 const string = `First               Second` 

Su conclusión dará aproximadamente lo siguiente.

 First               Second 

Es decir, cuando se ingresó este texto en el editor, es posible que el programador esperara que las palabras First y Second , al salir, aparecieran estrictamente una debajo de la otra, pero en realidad no es así. Para solucionar este problema, puede comenzar el texto de varias líneas con un avance de línea e, inmediatamente después de cerrar la comilla, llame al método trim() , que eliminará los espacios en blanco al principio o al final de la línea. Dichos caracteres, en particular, incluyen espacios y tabulaciones. Los caracteres de fin de línea también se eliminarán.

Se ve así.

 const string = ` First Second`.trim() 

▍ Interpolación


Por interpolación aquí queremos decir la conversión de variables y expresiones en cadenas. Esto se hace usando la construcción ${} .

 const variable = 'test' const string = `something ${ variable }` //something test 

Puede agregar cualquier cosa al bloque ${} , incluso expresiones.

 const string = `something ${1 + 2 + 3}` const string2 = `something ${foo() ? 'x' : 'y' }` 

El texto something 6 entrará en la string constante, ya sea el texto something x el texto something y se escribirá en la string constante2. Depende de si la función foo() devuelve verdadero o falso (el operador ternario se usa aquí, que, si lo que está antes del signo de interrogación es verdadero, devuelve lo que viene después del signo de interrogación, de lo contrario devuelve qué viene después del colon).

▍ Plantillas etiquetadas


Las plantillas etiquetadas se usan en muchas bibliotecas populares. Entre ellos se encuentran Styled Components , Apollo , GraphQL .

La salida de dichos patrones está sujeta a cierta lógica definida por la función. Aquí hay un ejemplo ligeramente revisado en una de nuestras publicaciones que ilustra cómo trabajar con cadenas de plantillas etiquetadas.

 const esth = 8 function helper(strs, ...keys) { const str1 = strs[0] //ES const str2 = strs[1] //is let additionalPart = '' if (keys[0] == 8) { //8   additionalPart = 'awesome' } else {   additionalPart = 'good' } return `${str1}${keys[0]}${str2}${additionalPart}.` } const es = helper`ES ${esth} is ` console.log(es) //ES 8 is awesome. 

Aquí, si el número 8 escrito en la constante esth , la línea ES 8 is awesome . De lo contrario, habrá otra línea. Por ejemplo, si esth número 6 , entonces parecerá que ES 6 is good .

Styled Components utiliza plantillas etiquetadas para definir cadenas CSS.

 const Button = styled.button` font-size: 1.5em; background-color: black; color: white; `; 

En Apollo, se utilizan para definir consultas GraphQL.

 const query = gql` query {   ... } ` 

Sabiendo cómo funcionan las plantillas etiquetadas, es fácil entender que styled.button y gql de los ejemplos anteriores son solo funciones.

 function gql(literals, ...expressions) { } 

Por ejemplo, la función gql() devuelve una cadena que puede ser el resultado de cualquier cálculo. El parámetro de literals de esta función es una matriz que contiene el contenido de un literal de plantilla dividido en partes, las expresions contienen los resultados de las expresiones de evaluación.

Analicemos la siguiente línea.

 const string = helper`something ${1 + 2 + 3} ` 

La función helper obtiene la matriz de literals contiene dos elementos. En el primero habrá something texto con un espacio después, en el segundo habrá una línea vacía, es decir, qué hay entre la expresión ${1 + 2 + 3} y el final de la línea. Habrá un elemento en la matriz de espressions : 6 .
Aquí hay un ejemplo más complejo.

 const string = helper`something another ${'x'} new line ${1 + 2 + 3} test` 

Aquí, en la función helper , la siguiente matriz se obtendrá como primer parámetro.

 [ 'something\nanother ', '\nnew line ', '\ntest' ] 

La segunda matriz se verá así.

 [ 'x', 6 ] 

Resumen


Hoy hablamos sobre el manejo de excepciones, sobre la sustitución automática de punto y coma y sobre los literales de plantilla en JavaScript. La próxima vez veremos algunos conceptos más importantes del lenguaje. En particular, trabaje en modo estricto, temporizadores, cálculos matemáticos.

Estimados lectores! ¿Utiliza las capacidades de las plantillas etiquetadas en JavaScript?

Source: https://habr.com/ru/post/es430376/


All Articles