Variables en Javascript y constantes

Variables en Javascript y constantes

Variables

Uno de los elementos más usados son las variables en Javascript. Podemos describir a las variables en Javascript como cajas para guardar información, las cuales etiquetamos para que podamos encontrar esa información fácilmente. Esta etiqueta es el nombre de la variable y la cajita es el espacio utilizado en la memoria RAM.

Variables y constantes, cajas que guardan información
Variables y constantes, cajas que guardan información

Así son las variables en Javascript, y de hecho en cualquier lenguaje de programación. También puedes almacenar cualquier tipo de dato, ya sean números, cadenas de texto, funciones o cualquier tipo de objeto.

Existen dos maneras de declarar una variable. Una es usando let y la otra usando var.

//Variables de tipo String
var nombre = 'Jaime';
let apellido = "Cervantes"

La forma var es la que siempre ha existido desde el origen del lenguaje, después en el 2015 apareció let con la finalidad de mitigar ciertas deficiencias de var. Por esta razón, la recomendación es usar let, de todos modos es importante conocer bien var debido a que te encontrarás con mucho código que use aún var.

¿Cómo se usan las variables en Javascript?

El nombre o identificador de una variable, no puede iniciar con un número, debe iniciar con alguna letra (incluyendo _ y $), y además Javascript es sensible a mayúsculas y minúsculas. No es lo mismo nombre y Nombre, estas son dos variables diferentes.

Las variables se definen de dos formas:

Con un solo let:

let nombre = 'Jaime',
    apellidoPaterno = 'Cervantes',
    apellidoMaterno = 'Velasco';

Un solo var:

var nombre = 'Jaime',
    apellidoPaterno = 'Cervantes',
    apellidoMaterno = 'Velasco';

Ahora con un let por cada variable:

let nombre = 'Jaime';
let apellidoPaterno = 'Cervantes';
let apellidoMaterno = 'Velasco';

Con un var por cada variable.

var nombre = 'Jaime';
var apellidoPaterno = 'Cervantes';
var apellidoMaterno = 'Velasco';

En el ejemplo anterior se define variables de tipo string (cadenas de texto), pero recuerda que puedes almacenar cualquier tipo de dato.

Es recomendable poner cada variable en su propia linea porque es más rápido de entender para el “tú” del futuro y tus compañeros que no han tocado tu código. Por ejemplo NO definas las variables así:

let nombre = 'Jaime', apellidoPaterno = 'Cervantes', apellidoMaterno = 'Velasco'; edad = 32, sexo = 'H'

Probemos con números.

let edad = 32.9;
let hijos = 1;
var edad = 32.9
var hijos = 1;

Los datos boleanos solo almacenan falso o verdadero.

let esHombre = true;
let esAlto = false;
var esHombre = true;
var esAlto = false;

Como su nombre lo dice, su valor puede ser variable, por lo tanto puedes reasignar un nuevo valor a tu variable:

var nombre = 'Jaime';
nombre = 'Pepito';
nombre = 'Menganito';
console.log(nombre); // 'Menganito'

Ámbitos de las variables en Javascript, let vs var

La principal diferencia entre las variables definidas con let y var es el ámbito que alcanzan cuando se declaran:

  • Con let tienes ámbito de bloque {}.
  • Con var tienes ámbito de función function () pero no de bloque.

Ejemplo del ámbito de bloque.

if (true) {
  let nombre = 'jaime';
}
console.log(nombre); // Uncaught ReferenceError: nombre is not defined

Porque let tiene ámbito de bloque, al querer acceder a la variable nombre Javascript muestra:

Uncaught ReferenceError: nombre is not defined

Tratar de usar ámbito de bloque con var.

if (true) {
  var nombre = 'Jaime';
}
console.log(nombre); // 'Jaime';

En este ejemplo la variable nombre si puede ser accedida desde afuera de los bloques, esto es porque no está dentro de ninguna función.

Ahora vamos a declarar la variable con var dentro de una función.

function setearNombre() {
  var nombre = 'Jaime';
}
setearNombre();
console.log(nombre); // Uncaught ReferenceError: nombre is not defined

Vamos a ver que pasa con let cuando intentamos usar ámbito de función.

function setearNombre() {
  let nombre = 'Jaime';
}
setearNombre();
console.log(nombre); // Uncaught ReferenceError: nombre is not defined

Si definimos una variable con let dentro de una función, tampoco podemos acceder a ella desde afuera, porque la propia definición de la función usa bloques {}.

Constantes en Javascript

Las constantes son de igual forma que las variables, cajitas etiquetadas para guardar información, con la única diferencia que no se le puede reasignar algún otro valor.

const nombre = "Jaime";
nombre = "Pepito"; // Uncaught TypeError: Assignment to constant variable 

No nos olvidemos de declarar cada constante en su propia linea para mejorar la lectura de nuestro código.

const nombre = "Jaime";
const apellidoPaterno = "Cervantes";
const apellidoMaterno = 'Velasco';
const nombre = 'Jaime',
    apellidoPaterno = 'Cervantes',
    apellidoMaterno = 'Velasco';

Mismas reglas que las variables con let

Las constantes siguen las mismas reglas de ámbito de bloque que las variables en Javascript con let.

Así como let, const tiene ámbito de bloque, por lo que si se define una variable con var y tiene el mismo nombre de una constante, se lanzara el siguiente error:

{
  const nombre = "Jaime";
  var nombre = "Pepito"; // Uncaught SyntaxError: Identifier 'nombre' has already been declared
}

Constantes en javascript de solo lectura y mutables

Las constantes son de solo lectura, es por eso que no se les puede reasignar un valor. Aun así estos valores guardados siguen conservando el comportamiento de su tipo de dato.

Por ejemplo, si se crea una constante de un objeto, si se pueden cambiar las propiedades de ese objeto.

Un objeto literal en JavaScript no es más que un conjunto de valores identificados con un nombre o clave, como lo siguiente:

const jaime = {
  nombre: "Jaime",
  apellidoPaterno: "Cervantes",
  apellidoMaterno: "Velasco"
};
jaime.nombre = "Pepito"; // todo bien, se puede cambiar una propiedad
jaime = {}; // Uncaught Type Error: Assigment to constant variable

La referencia al objeto es de solo lectura, pero no quiere decir que el valor sea inmutable. Como se ve en el ejemplo, se puede cambiar la propiedad, pero no reasignar un nuevo valor a la constante jaime como podemos comprobar en la última línea del ejemplo.

¿Cómo nombrar a las variables y constantes en Javascript?

Cualquier tonto puede escribir código que una computadora pueda entender. Los buenos programadores escriben código que los humanos pueden entender.

Martin Fowler

El objetivo principal del nombre de variables y constantes es entender inmediatamente que es lo que estamos guardando en ellas. Es importante describir correctamente el contenido de las variables, porque así le facilitamos la vida a la siguiente persona que necesite leer y modificar nuestro código.

Esta siguiente persona muy a menudo eres “tú” del futuro, y al menos que seas un robot, no podrás recordar cada detalle de tu código.

La mayor parte del tiempo utilizado por un programador es para leer y entender código, no queremos gastar mucho tiempo descifrando el contenido de ellas, como programadores somos más contentos creando cosas nuevas.

Por esta razón no debe sorprendernos la importancia en el nombramiento de nuestras variables y constantes, es una de las mejoras maneras para no malgastar nuestro tiempo y el tiempo de nuestros colegas.

Recomendaciones:

  • Dedica el tiempo suficiente para nombrar una variable. Es como organizar tu cuarto, entre más ordenado más rápido será encontrar el otro calcetín (me pasa mucha cuando no ordeno el mío) xD.
  • El nombre debe ser muy semántico y explicar el contexto del mismo. Evitar nombres como data o info porque no dicen mucho del contexto, es obvio que son datos e información, pero ¿Para qué? o ¿Qué?.
  • Ponte de acuerdo con tus colegas sobre como nombrar las variables, en especial aquellas que tiene mucha relación con el negocio. Por ejemplo para los datos de registro de un usuario, puede ser “registroDeUsuario”, “registroDeCliente”, “registroDeVisitante”, las tres formas pueden ser válidas (depende mucho el contexto), pero es mejor seguir una convención a través de un acuerdo.
  • Evita los nombres muy cortos como “u1”, “a2”, “_”, “_c”
  • Evita las abreviaciones, prefijos, sufijos e infijos. Estos son difíciles de entender. Por ejemplo pmContenido, ¿Qué es “pm”?
  • Si la variable o constante tiene un ámbito muy pequeño, es decir, es utilizada en líneas cercanas, entonces el nombre puede ser corto.
  • Si la variable o constante se utiliza en un ámbito grande, es decir, se hace referencia a ella a una distancia de muchas líneas, entonces el nombre debe ser muy descriptivo, y por lo tanto es normal que pueda ser largo.

Publicaciones relacionadas

https://www.pensemosweb.com/introduccion-javascript/
https://www.pensemosweb.com/javascript-scheme-self-java/
Javascript Event Loop, concurrencia y asíncrono

Javascript Event Loop, concurrencia y asíncrono

Javascript es secuencial

“Event loop”, tal vez lo has escuchado. Esto es porque javascript tiene modelo de ejecución de código donde utiliza un ciclo de eventos (event loop), que una vez entendiendo su funcionamiento, se puede crear código mucho más eficiente, y resolver problemas rápidamente, que a simple vista no son tan obvios. Es la base de la concurrencia y el asincronismo.

Para comenzar:

  • Javascript se ejecuta en un solo hilo de ejecución, como se ejecuta un solo hilo, su ejecución es secuencial, no es como JAVA donde se pueden lanzar otros hilos.
  • Existen ambientes huéspedes donde se ejecuta javascript que tienen su propia API, ejemplo:
    • Navegador web
    • Node.js
  • Este funcionamiento secuencial es el mismo, no cambia por estar relacionado con un ambiente huésped.
  • La concurrencia se logra a través de invocaciones asíncronas a la API del ambiente huésped, esto evita que el funcionamiento se bloquee y provoque lentitud de las aplicaciones.

Elementos para la concurrencia

Veamos con más detalle los elementos que hacen funcionar Javascript en los ambientes huéspedes.

  1. Call Stack – Pila de ejecuciones
  2. Callback Queue – Cola de retrollamadas, tambien llamado Task Queue
  3. Event Loop – Ciclo de eventos
  4. Host Environment – Funcionalidad del ambiente huésped
Event loop, ciclo de eventos javascript
Event loop, ciclo de eventos javascript

Calls Stack, heap y motor de javascript

Del lado izquierdo tenemos al motor de javascript, este motor se encarga de ejecutar nuestro código. A veces es llamado máquina virtual, porque se encarga de interpretar nuestro código a lenguaje máquina y ejecutarlo. Solo puede ejecutar una línea de código a la vez. Tiene un Heap para guardar objetos y demás datos en memoria que el código pueda generar.

Pero también tenemos una Pila de llamadas (Call Stack). Los elementos de la pila son objetos y datos de memoria, pero tienen una estructura especifica. Tienen un orden y el último elemento en entrar es el primero en salir, se le llama LIFO (Last-in, First-out).

Cada elemento de la pila es un trozo de código Javascript y guarda las referencias del contexto y variables utilizadas. La pila ejecuta el trozo de código en turno hasta quedar vacía.

Callbacks Queue

Abajo tenemos Callbacks Queue, es una estructura de datos y guarda pedazos de código que el motor de javascript puede ejecutar. Es una cola, y como la cola de las tortillas el primero en formarse, es el primero en salir (FIFO, First-in, First-out).

Un callback, es una función que se pasa por parámetro a otra, de tal manera que esta última ejecuta el callback en un punto determinado, cuando las condiciones y/o los datos cumplen una cierta regla de invocación.

Event loop

Event Loop, este elemento nos permite mover la siguiente callback del Callbacks Queue al Call Stack. Como es un ciclo, en cada iteración toma un solo callback.

Ambiente huésped

Del lado derecho tenemos El ambiente huésped, el ambiente huésped es el lugar donde corremos Javascript, los más comunes son el Navegador web y Node.js. Las tareas que ejecuta el ambiente huésped son independientes de los demás componentes. En el navegador web tiene sus propias API como fetch, setTimeout, alert. Node.js también cuenta con su propia API como net, path, crypto.

¿Cómo es posible?, ¿Y la concurrencia? ¿Puedo hacer muchas cosas a la vez en un sitio web?

Todo el trabajo de poner un temporizador, renderizar contenido como texto, imágenes, animaciones, o ver videos, están a cargo del ambiente huesped. Lo que pasa es que las APIs del navegador web generan callbacks cuando su tarea ya está completada y los agrega al Callbacks Queue para que el event loop las tome y las mueva al Call stack.

Javascript se comunica con el ambiente huésped a través de su API, mas adelante vamos a utilizar un ejemplo basado en el diagrama de arriba, donde se utiliza window.setTimeout, la cual es una función del navegador web.

Concurrencia

Inicio es la función principal, con la que se inicia el proceso de ejecución en el call stack. Dentro de inicio tenemos cuatro setTimeout de dos segundos. La función setTimeout es propia del ambiente huésped, y a los cuatro setTimeouts le pasamos un callback, estos son, cb1, cb2, cb3 y cb4.  

Los temporizadores setTimeout se ejecutan en la parte de la funcionalidad del ambiente huésped dejando tiempo de ejecución para el call stack. He aquí la concurrencia, mientras el ambiente huésped ejecuta un temporizador, el call stack puede continuar ejecutando código.

Después de los primeros dos segundos, el ambiente huésped, a través del primer setTimeout pasa cb1 al callback queue, pero durante estos dos segundos se pueden realizar otras operaciones en el ambiente huésped, en el caso del navegador, un ejemplo seria que el usuario puede seguir escribiendo dentro de un textarea. De nuevo, he aquí la concurrencia.

Tras el primer setTimeout, el segundo setTimeout pasa cb2 al callback queue y así sucesivamente hasta el cb4. Mientras los callbacks se pasan al callback queue. El event loop nunca deja de funcionar, por lo que en alguna iteración el event Loop pasa cb1 al call stack y se empieza a ejecutar el código de cb1 y esto mismo sucede con cb2, cb3 y cb4.

Event loop en acción

Aquí abajo esta el ejemplo del que hablamos, el temporizador genera los callbacks en el orden que aparecen los setTimeouts más dos segundos. El Event Loop toma un callback en cada iteración, por lo que cada cb de setTimeout se invocan uno después del otro, y no exactamente después de dos segundos, pues entre que se posicionan los callbacks en la cola y se mueven al call stack de ejecución transcurre más tiempo. Esto sin contar el tiempo que trascurre entre cada invocación de setTimeout.

Si en los cuatro callbacks se indica el mismo tiempo en milisegundos. Presiona el botón RERUN, Te darás cuenta de que los tiempos no son iguales y que pueden pasar más de dos segundos.

Conclusión

  1. Las APIs huéspedes reciben callbacks que deben insertar en la callback queue cuando el trabajo que se les encomienda esta hecho, por ejemplo un callback de una petición ajax se pasa a la callback queue solo cuando la petición ya obtuvo la respuesta. En el ejemplo que describimos arriba con setTimeout, cuando pasan dos segundos, se inserta el callback al callback queue.
  2. Mientras el ambiente huésped realiza sus tareas, en este caso, los demás temporizadores, el call stack de ejecución de javascript puede ejecutar el código que el event loop le puede pasar desde el callback queue.
  3. El Event loop es un ciclo infinito que mientras existan callbacks en el callback queue, pasara cada callback, uno por uno, al call stack.
  4. El call stack no puede ejecutar más de un código a la vez, va ejecutando desde el último elemento hasta el primero, en nuestro caso hasta la terminación de la función inicio que dio origen a todo el proceso. Es una estructura de datos tipo Pila.

Gracias a que los callbacks se ejecutan hasta que un trabajo específico esté terminado, proporciona una manera asíncrona de ejecutar tareas. Las tareas pueden realizarse en el ambiente huésped sin afectar la ejecución del call stack. En la pila solo se ejecuta código que recibe el resultado de las tareas realizadas por el ambiente huésped.

es_MXES_MX