Fundamentos de JavaScript 2020 ES6++ P1: Variables
JavaScript es el lenguaje de programación mas utilizado en el mundo, es el lenguaje estándar para los navegadores, y ha cambiado mucho desde sus raíces en 1995. En el 2015 se produjo el cambio más grande a JavaScript: ES6 (ECMAScript 2015) que alteró radicalmente la forma en la que escribimos JavaScript hoy en día. Vamos a repasar fundamentos de JavaScript para comenzar escribiendo código de una forma optima y actualizada desde el principio. JavaScript nos ofrece múltiples formas de escribir código, pero no usar ES6 es hacerse un gran daño a futuro.
var murió, declara variables con let y const.
Una variable es un valor que le asignamos a un nombre, o llave, que elegimos, en el próximo ejemplo voy a dejar claro la mejor practica para cada tipo de variable:
var noMeUses = 'No me uses nunca.';
let usaCuandoCambio = 'Yo puedo cambiar si quieres...';
const usaCuandoPuedas = 'Usame siempre que sea posible.';
Que es let?
Con ES6 JavaScript recibió let y const que reemplazaron completamente el uso de var. let origina de la palabra en ingles deja, en nuestro ejemplo estamos diciéndole al computador: deja que usaCuandoCambio sea igual a Yo puedo cambiar si quieres.... Usa let siempre que tengas que declarar un valor que cambie que no sea un objeto o arreglo (Array). Adicionalmente, el alcance de let es local a su bloque, que es una forma muy complicada de decir, que let existe dentro de el bloque de código dentro de llaves { } que fue declarado:
for (let i = 1; i <= 1; i++) {
var mensaje = 'hola';
console.log(mensaje); //'hola'
}
console.log(mensaje); //'hola'
for (let i = 1; i <= 1; i++) {
let mensaje2 = 'hola';
console.log(mensaje2); //'hola'
}
console.log(mensaje2); //'ReferenceError: mensaje is not defined'
En este ejemplo declaramos mensaje en un bucle for, cuando tratamos de acceder al valor de mensaje por fuera del for, tenemos un error de referencia porque mensaje no ha sido definida. Esto quiere decir que no podemos leer o cambiar el valor de mensaje por fuera de su contexto/alcance local.
Declaracion de variables con let vs var
Usando var podríamos acceder y cambiar el valor de mensaje cuando quisiéramos, incluso declararlo múltiples veces, lo cual es un océano de errores esperando inundar tu código. Este error no nos sucede utilizando let debido a que no podemos re-declarar let con el mismo nombre:
var gato = 'gato'; //'gato'
var gato = 'perro'; //'perro'
let pato = 'pato'; //'pato'
let pato = 'conejo'; //'Identifier 'pato' has already been declared'
Usando var pudimos declarar gato y cambiarlo a perro y JavaScript no le importo en lo absoluto. Si diferentes partes de tu código utilizan la misma variable, y esta la cambias por accidente declarándola dos veces, vas a tener muchos problemas.
Re-declarar y alterar variables con let vs var
También podemos re-declarar o alterar valores dentro de llaves {} y alterar el valor var original, esto es especialmente problemático cuando se utilizan nombres de variables genéricos dentro de for, if, o funciones (ej: i o indice):
var indice = 3; //3
for (let i = 1; i <= 1; i++) {
var indice = 100; //100
console.log(indice); //100
}
console.log(indice); //100
let indice2 = 3; //3
for (let i = 1; i <= 1; i++) {
let indice2 = 100; //100
console.log(indice); //100
}
console.log(indice2); //3
En este ejemplo podemos ver que se puede re-utilizar nombres para variables declaradas con let sin alterar las que tenemos declaradas en otro contexto.
Let se puede acceder por cualquier operación dentro de su contexto o uno mas profundo, afortunadamente solo se puede alterar si no la re-declaramos:
//Re-declarado: Seguro
for (let i = 1; i <= 1; i++) {
let mensaje = 'hola';
for (let i = 1; i <= 1; i++) {
let mensaje = 'bai';
console.log(mensaje); //'bai'
}
console.log(mensaje); //'hola'
}
//Re-asignado: Cuidado
for (let i = 1; i <= 1; i++) {
let mensaje = 'hola';
for (let i = 1; i <= 1; i++) {
mensaje = 'bai';
console.log(mensaje); //'bai'
}
console.log(mensaje); //'bai'
}
Resumen de let
Usa let sobre var siempre, puedes re-declarar variables con nombres que te gustan sin causar errores, puedes estar seguro de que no vas a alterar un valor en una operación por equivocación, y si re-utilizas un nombre dentro del mismo alcance/contexto JavaScript te lo hará saber con un error previniendo que tu código corra de manera inesperada.
Que es const?
Const se origina de constante, o valores que no cambian, sin embargo const unicamente se comporta como constante para valores primitivos. Cuando se declara un objeto o arreglo const permite cambios, por esto es buena practica usar const para cualquier arreglo u objeto que declaremos. Todas las reglas de el alcance/contexto de let aplican para const tambien
const con primitivos
Hay 6 valores primitivos en JavaScript, los mas comunes son string, numero, y boolean que son el 99% de los primitivos que se ven. Cuando se utiliza const con primitivos, no se pueden re-asignar:
const pi = 3.14; // 3.14
pi = 2; // 'TypeError: Assignment to constant variable.'
const gato = 'gato';
gato = 'perro'; // 'TypeError: Assignment to constant variable.'
const siempreUsarLetYConst = true;
siempreUsarLetYConst = false; // 'TypeError: Assignment to constant variable.'
En el caso de los primitivos, const es inmutable.
const con no-primitivos
Siempre que tratemos de re-asignar, o re-declarar const se produce un error. Sin embargo, con los no-primitivos podemos alterar los valores de const. Los no-primitivos mas comunes son objetos, arreglos, y funciones que son el 99% de los que se ven, pero en realidad todo lo que no es un primitivo en JavaScript es un objeto, pero esto es un tema para otro momento. En los ejemplos vamos a ver diferencias en alterar y re-asignar valores en objetos y arreglos:
const morsa = {}; // {}
morsa.nombre = 'Orsa'; // { nombre: 'Orsa' }
morsa = { nombre: 'Orsa' }; //'TypeError: Assignment to constant variable.'
const morsa = {}; //'SyntaxError: Identifier 'objeto' has already been declared'
const manada = [];
manada[0] = 'Orsa'; // ['Orsa']
manada = ['Orsa']; //'TypeError: Assignment to constant variable.'
const manada = []; //'SyntaxError: Identifier 'objeto' has already been declared'
En el primer ejemplo alteramos el valor de el objeto morsa agregándole una nueva pareja de llave:valor nombre: 'Orsa'. A pesar de que el resultado es el mismo en el ejemplo siguiente ejemplo estamos re-asignando una constante, lo cual no es permitido. Al final, tratamos de re-declarar la constante, lo cual no esta permitido igual que vimos en let. Pasó exactamente lo mismo con el arreglo, pudimos alterar el valor agregándole un nuevo valor, pero no podemos re-asignar, o re-declarar.
Convencion de uso de const
La convención es utilizar const con cualquier arreglo, objeto, o funcion. Nos permite mutar los datos, pero nos cuida de accidentalmente re-asignarlos, lo cual seria posible con let. Adicionalmente los no-primitivos tienen metodos (funciones internas) para navegar datos, y en algunos casos multarlos.
const manada = [];
manada.push('Orsa'); //['Orsa']
manada.push('Moerse'); //['Orsa', 'Moerse']
const orsa = {
nombre: 'Orsa',
hobby: 'conspirar',
conspirar: () => console.log('Tengo un plan...'),
};
orsa.conspirar(); // 'Tengo un plan...'
Bonus: Levantamiento e Inicializacion
Cuando uno declara un valor, JavaScript lo procesa o levanta (hoisting) antes de ejecutar cualquier parte del código. Cuando JavaScript levanta un var también la inicializa, esto quiere decir que le asigna un valor de indefinido (undefined):
console.log(morsa); //undefined
var morsa = 'Orsa';
console.log(morsa); // Orsa
Uno pensaria que no se puede acceder a una variable antes de que fuera declarada, sin embargo JavaScript levanta e inicializa var. Esto abre la posibilidad de intentar utilizar una variable antes de que la declaráramos en nuestro código sin disparar un error, que podría llevar a comportamiento inesperado sin disparar un error.
JavaScript tambien levanta a let y const, sin emargo no las inicializa:
console.log(morsa); //ReferenceError: Cannot access 'morsa' before initialization
let morsa = 'Orsa';
console.log(morsa);
A pesar de que morsa fue levantada, nos genera un error si la tratamos de utilizar antes de que la declaremos en nuestro código porque JavaScript no la inicializa. Otro punto a favor para let y const.
Cuando se declaran funciones con const se levanta la funcion pero no se inicializa:
hai(); //ReferenceError: Cannot access 'hai' before initialization
const hai = () => console.log('hai');
hai();
Por esto es mejor practica utilizar const para declarar funciones. Habrá mas sobre funciones en otro articulo.
Conclusión
En JavaScript tenemos muchas opciones para todo, es importante ser constante en nuestro código e intentar mantener mejores practicas duraderas. Desde ES6 let y const se volvieron el nuevo estándar, var no sera sino una mala memoria de bases de código heredado. Solamente hay que seguir dos reglas sencillas:
- Utilizar let para strings, numeros, y booleans que deberían cambiar.
- Utiliza const para todos los objetos, funciones, y arreglos, y para strings, numeros, y booleans que no deberían cambiar.
El mundo ya esta en ES6, no se queden atrás!