Como cualquier otro lenguaje de programación, JavaScript utiliza variables para almacenar valores. Una variable es como una caja, a la cual podemos poner un nombre para identificarla posteriormente.
Aunque podemos escribir las variables en JavaScript con la sintaxis que prefiramos, la convención es utilizar:
- camelCase para variables
- SCREAMING_SNAKE_CASE para constantes
La diferencia entre una variable y una constante es que, mientras la variable está pensada para alterar su valor, el valor de la constante debería permanecer inalterado.
Declaración de variables: cómo asignar valores a una variable
Existen tres keywords que nos permiten declarar una variable en JavaScript:
var
var es una keyword "antigua", que declara variables globales. En ocasiones generan problemas debido al proceso de hoisting: cuando la máquina analiza un script, antes de ejecutarlo, procesará las declaraciones var
, lo que nos permite utilizar la variable antes de haberla declarado siquiera.
- Aunque esto pueda parecer una ventaja, se entiende como una mala práctica, ya que estamos utilizando código que todavía no hemos declarado, lo que puede conducir a errores.
- Además, las variables declaradas con
var
pueden redeclararse sin disparar errores, por lo que podemos sobreescribir accidentalmente nuestro código. No solo eso: la declaraciónvar
sobreescribirá cualquier declaraciónfunction
con el mismo nombre, así que ni siquiera podemos estar seguros de que nuestra declaración se vaya a sobreescribir por el hecho de venir en un momento posterior del script. - Por último, las variables
var
se declaran de forma global y pueden tener el mismo nombre que el parámetro de la función en la que se declaren. En definitiva, esto genera problemas de scope que en general hacen indeseable el uso de la keywordvar
.
let
let es una keyword introducida por ES6 para evitar algunos problemas de var
, que nos permite declarar variables re-asignables a nivel de bloque. Podemos inicializarla o no, con cualquier expresión legal.
El scope de let
se limita a la declaración de bloque, switch, try-catch, for, al cuerpo de una función, al módulo (ejecución de módulos) o al global scope (ejecución de script). Sus diferencias con var
incluyen:
- Las declaraciones
let
se limitan al scope del bloque. - Solo se puede acceder a su valor después de la declaración (no se les aplica el
hoisting
). - No crean propiedades en
globalThis
. - Tampoco pueden re-declararse en el mismo scope.
- Ni se pueden utilizar como el cuerpo único de un bloque (pues resultarían inaccesibles).
Temporal Dead Zone (TDZ)
Se llama Temporal Dead Zone (TDZ) al tiempo que pasa desde el inicio del script hasta que la variable declarada con let
, const
(la abordaremos en el siguiente bloque) o class
(se abordará en lecciones más avanzadas) se declara e inicializa en el script.
Tratar de acceder a una variable durante la TDZ resulta en un error de referencia. Alcanzado el momento de declaración, si no se ha inicializado, el valor de la variable será undefined
.
const
const, es otra keyword introducida por ES6 que, de nuevo, nos ayuda a evitar problemas derivados del hoisting
. A grandes rasgos funciona como una declaración let
, con la principal diferencia de que su valor no puede ser reasignado dentro del mismo scope.
Precisamente por ello, consideramos buena práctica utilizar const
siempre que sea posible, ya que:
- Indicamos a otros programadores que no tenemos la intención de alterar el valor almacenado.
- E impedimos que nosotros mismos podamos cambiarlo por error.
Sintaxis
Todas las keywords de declaración de variables se utilizan del mismo modo:
var myFirstVariable = 1;
let mySecondVariable = 2;
const myThirdVariable = 3;
Donde utilizamos la keyword seleccionada, seguida del nombre que queramos poner a la variable, seguida del operador de asignación =
, seguido del valor a asignar. Por último, cerramos la expresión con un punto y coma.
Declaración de funciones
Para declarar una función en JavaScript podemos utilizar otra keyword de inicialización: function
. function es una palabra clabe que vinculará una nueva función al nombre que hayamos seleccionado. Estas funciones pueden tomar argumentos entre paréntesis y devolver valores con la keyword return
, como en el ejemplo:
function addTwoNumbers(num1, num2) {
return num1 + num2;
}
Tras declarar una función, podemos ejecutarla utilizando su nombre seguido de paréntesis. Entre los paréntesis podremos proporcionar los argumentos que necesitemos. Una vez ejecutada la función, devolverá el valor indicado en el return:
addTwoNumbers(1, 2); // 3
Los módulos en JavaScript
En JavaScript podemos exportar funciones, constantes y variables para utilizarlas en otros archivos. Para ello disponemos de la keyword export
. Una vez exportada la declaración, podemos importarla a otro archivo mediante la keyword import
.
// Archivo utils.js
export function addTwoNumbers() {}
// Archivo index.js
import { addTwoNumbers } from './utils.js';
Named exports
A la hora de exportar una constante, variable o función, podemos hacerlo utilizando su nombre, como en el ejemplo anterior. En este caso hablamos de un named export
, ya que identificaremos el elemento exportado por su nombre. Esta técnica es útil cuando queremos exportar diferentes elementos del mismo módulo, ya que necesitaremos algún modo de identificar cada uno de ellos.
Default exports
Otra opción que nos ofrece JavaScript es exportar un elemento principal, que será la importación por defecto:
// Archivo utils.js
export default function addTwoNumbers() {}
// Archivo index.js
import addTwoNumbers from './utils.js';
En este caso necesitamos utilizar la keyword default al hacer la exportación, pero no necesitaremos las llaves en torno al nombre al hacer la importación. Esto se debe a que estaremos poniendo el nombre que necesitemos al export default del módulo en cuestión.
Los export default y named son compatibles:
// Archivo utils.js
export default function addTwoNumbers() {}
export const EXAMPLE = 'test';
// Archivo index.js
import addTwoNumbers, { EXAMPLE } from './utils.js';
Cómo renombrar importaciones
Debido a que la exportación por defecto de un módulo siempre es el mismo código (el que hayamos identificado con las keywords export default
), al hacer la importación a otro módulo podemos ponerle el nombre que queramos:
// Archivo utils.js
export default function addTwoNumbers() {}
// Archivo index.js
import newNameForThisFunction from './utils.js';
En el caso de que estemos utilizando named exports la cosa se complica, ya que necesitamos identificar qué elemento estamos importando y cuál es el nombre que le queremos poner. Para ello podemos utilizar la keyword as
, que nos permite introducir un alias:
// Archivo utils.js
export function addTwoNumbers() {}
// Archivo index.js
import { addTwoNumbers as newNameForThisFunction } from './utils.js';
Conceptos abordados
- var
- let
- const
- function
- import
- export