ES6: el remozado JavaScript. Parte I: variables y constantes

2
7808

Índice de contenidos

1. Introducción

Ya hace tiempo que la nueva especificación que rige JavaScript viera la luz, y llegó pertrechada de novedades. Sin embargo, hay quien opina que su venida se demoró demasiado, y ahora tiene que ganar terreno frente a otros lenguajes, que parecen estarle ganando por la mano. Pero tiene la ventaja y virtud de que es un estándar, así que acabará sobreponiéndose.

Ningún programador que hubiera trabajado con JavaScript se mostraba indiferente: o bien eran auténticos defensores a ultranza de dicho lenguaje, o bien sus más fervientes detractores. Yo me encuentro en el primer grupo, pero comprendo perfectamente al segundo.

El mayor punto de frustración con el que se topa un desarrollador bregado en programación orientada a objetos, es que JavaScript le parece un “quiero y no puedo”, que carece de herencia, de polimorfismo y de tipos, e intenta trasladar sus hábitos, a veces mediante ingeniosas triquiñuelas, a un lenguaje que puede instanciar un objeto sin ni siquiera haber definido su clase. Y es que JavaScript usa un paradigma de programación orientada a prototipos, que está pensado para ejecutarse y no consumir grandes recursos. Simplemente es diferente. Es otra cosa. No es Java, ni se comporta como Java. Pero en cuanto lo entiendes, empiezas a apreciarlo, y a disfrutar de sus matices.

Claro, que a veces tiene cosas que exasperan a cualquiera. Por ejemplo, abra la consola de su navegador y compruebe cómo 0.1 + 0.2 no es 0.3…

– ¿¿¿Cómo???

A ver, a ver, vamos más despacio, ¿cómo que es falso?

¡Ahhhhhhhh! ¿y eso? …

Es como el chiste: ¿Qué prefieres? ¿velocidad o precisión?

En fin, eso es porque implementa el estándar definido en la aritmética de punto flotante IEEE-754, y es inherente a muchos lenguajes de programación, incluidos todos los lenguajes EcmaScript (JavaScript, ActionScript, etc…). Si quieres conocer más detalles de esta imprecisión, en el post “Why is 0.1+0.2 not equal to 0.3 in most programming languages?” lo explica muy bien.

Pero vamos a empezar con las novedades de esta nueva implementación de JavaScript. El nombre oficial es ECMA 262, 6ª Edición, pero es conocido como ES6, ECMAScript 6, o ES2015, dado que su especificación se liberó en Junio de 2015.

Su principal cambio, respecto a versiones anteriores de la especificación, es que introduce una nueva sintaxis manteniendo la retrocompatibilidad, es modular, y esta vez sí que tiene una forma directa de definir clases y herencia.

2. Declaración de variables.

Una de las razones por las que JavaScript no gusta a muchos programadores, es que el ámbito de las variables no es el mismo que en otros lenguajes, siendo en muchos casos variables globales.

function foo(){
  for (var i=0; i<10; i++){
    console.log(i);
  }

  console.log(i + 3); //devuelve 13
}

En el ejemplo anterior vemos que la variable i sigue existiendo fuera del bucle y además conserva su último valor 10.

Desde la concepción de JavaScript, las variables declaradas dentro de un bloque se mueven al principio del bloque en tiempo de interpretación. Eso hace que siempre las podamos referenciar sin que dé error. Este proceder se llama hoisting. En el caso que nos ocupa sería:

function foo(){
  var i;
  for (i=0; i<10; i++){
    console.log(i);
  }

  console.log(i + 3); //devuelve 13
}

En ES6 sí se introduce una nueva forma de declarar variables, que es mediante la palabra reservada let. El ámbito de las variables así definidas está limitado al bloque donde se han declarado y no hacen hoisting.

function foo(){
  var a = 3;  
  if (a < 5){
    let b = 10;
    console.log(a + b); //devuelve 13
  }

  console.log(b); //b no está definida fuera del if
}

La variable b no está viva fuera del bloque definido por las llaves del if. Si se ejecuta está función el intérprete de JavaScript debería dar un ReferenceError al intentar referirse a una variable que no existe.

Esto es especialmente útil en los bucles que llaman a funciones. Recordemos que JavaScript permite la programación funcional, y pasar otra función como argumento de una función. Un caso particular de este hecho son los callbacks.

let vocales = ['a','e','i','o','u'];

function foo(){
  for (var i=0; i < 5; i++){

    bar(function(){
      console.log('La vocal es :' + vocales[i]);
    });
  }
}

En este caso es evidente y casi inmediato, pero imagenemos por un momento que la función bar() es muy compleja. Cuando se empiece a ejecutar el primer callback es muy probable que el bucle haya terminado, y como i es una variable que sigue existiendo al salir del bucle puede acabar llamando al callback con el valor equivocado.

Antaño, esto se solucionaba pasando la variable como parámetro al callback. Pero ahora podemos usar let, y el ámbito estará definido en la ejecución de dicho callback.

let vocales = ['a','e','i','o','u'];

function foo(){
  for (let i=0; i < 5; i++){

    bar(function(){
      console.log('La vocal es :' + vocales[i]);
    });
  }
}

Las variables declaradas con let aunque pueden ser sobreescritas, no pueden volver a ser declaradas en el mismo bloque.

Entonces, ¿por qué el siguiente código no da error?

Porque se pueden declarar variables con el mismo nombre usando let siempre que estén declaradas en distintos bloques. Al tener distinto ámbito, se trata de variables diferentes aunque tengan el mismo nombre. Otra cosa, es que por claridad y legibilidad sea conveniente.

let version = '';
version = '1.2';
console.log(version); //version vale 1.2

if (version != ""){
  let version = '1.3';
  console.log(version); //version vale 1.3
}

console.log(version); //version vale 1.2

3. Constantes

Por fin se pueden definir constantes en JavaScript mediante la palabra reservada const. Al declararla es obligatorio definir su valor, y luego sólo podrá ser consultada.

const MAX_SIZE = 4;

for (let i=0; i < MAX_SIZE; i++){
  console.log(i);
}

Una vez declarada no podrá ser modificada, y arrojará un error si se intenta.

Por otro lado, el ámbito de las constantes se limita al bloque donde se han declarado.

const MAX_SIZE = 4;

for (let i=0; i < MAX_SIZE; i++){
  const MSG = "La variable es: "
  console.log(MSG + i);
}
console.log(MSG); //daría error porque MSG aquí no está definida

El resultado de ejecutar el código anterior es:

Hay que tener en cuenta que las constantes también pueden ser objetos y como constantes, si intentamos volver a asignarles un valor nos dará el correspondiente error:

Sin embargo, y aunque no podemos asignar un nuevo objeto a esa constante, sí que podemos modificar las propiedades de dicho objeto. Hay que entender cómo funciona por debajo: con la palabra reservada const estamos asignando un nombre a una dirección de memoria. Y a ese nombre no le podremos asignar otra dirección de memoria distinta al tratarse de una constante. Pero al tratarse de un objeto, si podemos modificar sus propiedades sin modificar su dirección de memoria. Así, podríamos hacer lo siguiente y no daría error:

const GAME = {lives: 3, width: 500, height: 300};
console.log(GAME.lives);  //el resultado será 3

GAME.lives = 5;
console.log(GAME.lives);  //el resultado será 5

Si lo que queremos es definir un objeto inmutable como constante sería utilizando Object.freeze().

const GAME = Object.freeze({lives: 3, width: 500, height: 300});

//es GAME inmutable?
Object.isFrozen(GAME);

Y comprobaríamos que dicho objeto es inmutable con Object.isFrozen().

[alert type=»warning» close=»false»]Este post está formado de tres partes y en breve se publicará la siguiente: ES6: el remozado JavaScript. Funciones, Objetos y Arrays[/alert]

2 COMENTARIOS

  1. Muchas gracias por esto tutoriales, lo que no comentas en esta sección es que pasa con «var» a la hora de declarar variables, si es recomendable usarla y en que ámbitos ser debería usar, ahora que tenemos el let y el conts.

    • Lo cierto es que recomiendo usar la última versión del estándar. Que efectivamente hace uso de let y de const. En un script nuevo no veo ninguna necesidad de usar la declaración de variables mediante var. Sólo tendría sentido mantenerla por retrocompatibilidad con navegadores muy antiguos que no soporten esta versión de javaScript. Pero desde que los navegadores son evergreen, siguen una estrategia de actualización silenciosa, que les permite irse adaptando a los últimos estándares de forma transparente. Así que la mayoría de navegadores sí lo soportarán.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad