El lenguaje JavaScript
Introducción a JavaScript
En este capítulo, describiremos rápidamente el lenguaje JavaScript, suponiendo que domina al menos un lenguaje informático y los conceptos básicos (tipado, variables, estructuras condicionales y iterativas, etc..) de la programación.
1. Breve repaso histórico
JavaScript es un lenguaje de programación creado en 1995 por Brendan Eich, que trabajaba para la sociedad Netscape. El objetivo original del lenguaje era crear scripts, es decir, programas interpretados que se ejecutan por un navegador, principalmente para manipular los datos del DOM (Document Object Model), es decir, los objetos (en sentido informático del término), que representan los elementos del documento etiquetado (por ejemplo, una página HTML) y asignado en memoria del navegador.
A continuación, JavaScript evolucionó mucho funcionalmente (por ejemplo, permitiendo el acceso asíncrono a los datos proporcionados por el servidor) e incluso ha invertido recientemente en el «lado servidor», con el entorno Node.js.
A pesar de su nombre, que puede dar lugar a confusión, JavaScript tiene muy poca relación con el lenguaje Java (solo algunas estructuras sintácticas que provienen del lenguaje C).
El lenguaje JavaScript se sitúa en la confluencia de dos paradigmas de programación: el paradigma de la programación funcional...
¿Dónde escribir código JavaScript?
Para una utilización del lado cliente fuera del «bundlelización» (veremos más adelante qué es un bundle), el código JavaScript se debe externalizar en archivos de extensión .js y relacionar con el código HTML a través de la etiqueta <script>, como en el siguiente.
Consideremos el script JavaScript llamado hola.js:
console.log("Hola");
Y la página HTML test.html, que implementa este script:
<html>
<head>
<script src="hola.js"
type="text/javascript" language="javascript">
</script>
</head>
<body> JavaScript le dice hola en la consola </body>
</html>
Este ejemplo de código se ejecuta habiendo sido cargado (abierto) en su navegador.
Los mensajes generados por el método log() del objeto console, se muestran en las consolas que forman parte de las herramientas del navegador (pulse la tecla [F12] para que aparezcan).
Si utilizará una versión antigua de un navegador, es muy importante no utilizar una etiqueta <script> auto-cerrada.
Si crea código JavaScript con un framework (por ejemplo, Angular), será el propio framework...
Las herramientas del navegador y la depuración
Las herramientas del navegador (pulse la tecla [F12] para mostrar un número determinado), le permite entre otras cosas:
-
Gracias a las consolas, visualizar los mensajes emitidos:
-
Por el intérprete JavaScript, principalmente los errores de programación (los enlaces pulsables, le permiten posicionarse en las líneas de código con error).
-
Por su código (como en el ejemplo anterior).
-
Gracias a las pestañas llamadas Elementos, HTML..., mostrar la jerarquía de las etiquetas de la página web.
-
Gracias a las pestañas llamadas Inspector DOM..., mostrar la jerarquía de los objetos asignados en memoria del navegador y que se corresponden con todos los documentos cargados en todas las pestañas del navegador.
Algunos navegadores ofrecen dos consolas:
-
La consola web que muestra los mensajes (emitidos por los scripts JavaScript o relativos a las cargas de los recursos inducidos), relativos al recurso cargado en la pestaña actual.
-
La consola del navegador, que muestra los mensajes relativos a los recursos cargados en todas las pestañas.
Los elementos de programación básicos
La sintaxis «básica» de la programación en JavaScript, es la del lenguaje C, que a su vez fue adoptada por el lenguaje Java, pero esta sintaxis se ha estandarizado por ECMAScript, que define un conjunto de normas de programación.
1. Las variables
Las variables son tipadas dinámicamente (y no durante sus declaraciones). Se declaran por:
-
La palabra reservada var: el ámbito de la variable es el de la función en la que parece (pero no las funciones incluidas): desde la creación de la palabra reservada let, este tipado es muy desaconsejable.
-
La palabra reservada let: el ámbito de la variable está sujeta al bloque de instrucciones.
-
La palabra reservada const: la variable solo es accesible en modo lectura.
a. Los tipos internos
JavaScript tipa (de manera interna) las variables, según seis tipos primitivos:
-
Un tipo booleano: true y false.
-
Un tipo nul: null.
-
Un tipo indefinido (resultado de los accesos a una variable que no existe o no tiene valor): undefined.
-
Ejemplo de variable creada, pero de valor indefinido: var i.
-
Un tipo para los números que sean enteros o reales: number.
-
Un tipo para las cadenas de caracteres: string.
Las cadenas de caracteres se pueden rodear por comillas simples o dobles; veremos en nuestros ejemplos que generalmente los rodeamos por dobles comillas.
-
Un tipo para los símbolos (este tipo se introdujo por ECMAScript 6 y no se desarrollará aquí).
Y el tipo Object en el resto de casos. Por lo tanto, JavaScript es un lenguaje orientado a objetos.
A continuación se muestran algunos ejemplos de creación de variables escalares (simplificando las cadenas de caracteres en esta categoría):
var raro; // su valor es: undefined
var i = 0;
let bool = true;
const nombre = "Pierre";
El tipo de una variable se puede probar por la función typeof().
b. El transtipado
Diferentes funciones y operadores que permiten transtipar un valor. Los más útiles en JavaScript son aquellos que transforman una cadena de caracteres (string) en un valor numérico (number):
-
parseInt(<string>) extrae (si existe) el valor entero utilizado como prefijo de la cadena:
parseInt("123.45") devuelve 123.
parseInt("123.45bla") devuelve 123.
-
parseFloat(<string>) extrae (si existe)...
La programación funcional en JavaScript
JavaScript se sitúa en el paradigma de la programación funcional: en este paradigma, las funciones son elementos de primer plano del lenguaje.
En JavaScript:
-
Una función se puede pasar como argumento a una función host. La función que se pasa como argumento, se llama función de callback (o función de rellamada).
-
Una función (normalmente llamada factory), también puede devolver una función.
1. Una función que se pasa como argumento (función de callback)
La utilización de las funciones de callback, es un elemento esencial del lenguaje JavaScript.
Pasar una función como argumento de una función host, permite generalmente definir el código:
-
que se debe ejecutar al final de la ejecución de la función (pero posiblemente también durante la ejecución de la función);
-
que consume los datos producidos por la función.
Utilizar funciones de callback es un esquema de programación muy frecuente en JavaScript, durante el acceso asíncrono a los datos.
A través de los dos métodos forEach() y map() aplicados a las listas, damos a continuación dos ejemplos del uso de los métodos de callback.
a. Ejemplo con el método forEach()
A continuación se muestra un ejemplo de utilización de una función de callback con el método...
La programación orientada a objetos con JavaScript
1. Los principios de la programación orientada a objetos con JavaScript
Casi todo es objeto en JavaScript. Sin embargo, este lenguaje no gestiona las clases (al contrario de lo que sucede, por ejemplo, con los lenguajes Java, C++ o Python) antes de su normalización por la norma ECMAScript 6 (en 2015, es decir, veinte años después de su creación). Vamos a basarnos en esta evolución principal para presentar la programación orientada a objetos con JavaScript, en tres momentos diferentes:
-
La gestión clásica de los objetos, sin utilización de clases para instanciarlas.
-
La introducción de las clases y de una herencia simplificada, con la norma ECMAScript 6.
-
La utilización de extensiones del lenguaje JavaScript, para gestionar las clases, principalmente con TypeScript (este último punto será el objeto del capítulo siguiente).
En su gestión tradicional (sin clases), los objetos se pueden crear de dos maneras:
-
De manera literal, utilizando las llaves.
-
Utilizando una función constructora y llamando a esta función a través de la instrucción new.
La herencia está garantizada por los objetos particulares llamados prototipos: es la herencia por delegación.
2. Los objetos literales
JavaScript se distingue de muchos otros lenguajes de programación, por el hecho de que los objetos se pueden crear de manera literal (y no son instancias de clase). La sintaxis que permite formatear estos objetos cuando se serializan, se llama JSON (JavaScript Object Notation). Esta sintaxis se ha convertido en algo extremadamente popular en el intercambio de datos (en detrimento de XML).
La gestión de las clases en JavaScript se ha introducido a través de la norma ECMAScript 6 y sobre todo, por las extensiones del lenguaje JavaScript como TypeScript o Dart (ver la webografía).
Suponga un objeto topPhone que se define como sigue:
let topPhone = {"type": "phone", "brand": "Peach", "name":
"topPhone"};
Usando las llaves, el objeto creado hereda el «meta-objeto» Object (este punto se detallará más adelante).
Una propiedad de un objeto puede tener cualquier valor:
-
Un valor booleano.
-
Un valor escalar (un entero, un real, una cadena de caracteres, etc...)....
Las principales aportaciones de la norme ECMAScript 6
1. La norma ECMAScript
ECMAScript es un conjunto de normas de programación recomendadas para los lenguajes de script. Estas normas se aplican principalmente por los intérpretes JavaScript (los de los navegadores y por Node.js).
Estas recomendaciones son muy numerosas, por lo que solo detallaremos algunas de ellas, de las definidas en 2015 (norma ECMAScript 6), que han hecho evolucionar considerablemente el lenguaje y que son ampliamente difundidas, desde:
-
la palabra reservada let;
-
la interpolación de las variables en las cadenas de caracteres;
-
los argumentos por defecto;
-
la manipulación más cómoda de las listas con:
-
la estructura iterativa for (... of ...)...;
-
el método includes() para probar la presencia de un elemento;
-
la utilización de las fat arrows para simplificar la escritura de las funciones de callback;
-
las clases.
2. La palabra reservada let
La palabra reservada let limita el ámbito de la variable que se introduce en el bloque de instrucciones actual.
Por ejemplo, se utiliza de manera sistemática para las variables locales a las estructuras iterativas:
for (let <variable> in ...) { ... }
for (let <variable> of ...) { ... }
Es posible que haya tenido que utilizar la directiva use strict para utilizar esta palabra reservada.
3. La interpolación de variables en las cadenas...
La programación reactiva, observables y promises (promesas)
Los observables son los elementos clave de la programación reactiva.
Observables es cualquier entidad de un programa, que puede producir un flujo de eventos capturables a lo largo del tiempo: esto puede ser un control de la interfaz que se activa (por ejemplo, un botón que se pulsa) o una variable que va a cambiar de valor (en este caso, los eventos se asocian a valores significativos). El objetivo de la programación reactiva, es poder asociar de manera asíncrona una operación a los valores emitidos por el observable (la operación se asocia al observable a través de una suscripción). Más particularmente, una función se podrá ejecutar para cada valor recibido, otra en caso de error y para terminar, una última en caso de fin explícito del flujo (las dos últimas funciones se podrían ocultar). Estas funciones son los observadores (observers), bien conocidos por el patrón de diseño «observador».
Este paradigma se implementa en JavaScript, a través de la librería RxJS (y en el momento de la redacción de este libro, en curso de normalización bajo ECMAScript).
La librería RxJS se puede utilizar como módulo de Node.js o como un archivo a relacionar con un código HTML.
Para utilizarla en el ecosistema de Node.js (ver el capítulo La plataforma Node.js), conservando una compatibilidad con el código JavaScript anteriores, es necesario instalar con el administrador de módulos npm, los dos módulos rxjs y rxjs-compat (la opción save que permite especificar estás instalaciones en el archivo package.json cuya la utilidad se verá más adelante en este libro):
npm install rxjs --save
npm install rxjs-compat --save
Para utilizarla directamente en un código HTML, también es necesario utilizar npm con el comando npm install -g rx-lite, y después volver a copiar el archivo rx.lite.min.js en el directorio donde se localiza el código HTML.
A continuación se muestra la creación de un observable, en un código ejecutado con Node.js:
var Rx = require('rxjs-compat'); ...