17 octubre, 2008

Apuntes sobre JavaScript 2.0

Llevo tiempo retrasando este artículo (de hecho está incompleto) sobre ECMAscript 4 (también conocido como Javascript 2) pero han habido cambios importantes en la especificación que parecen querer conservar la simplicidad y flexibilidad que han hecho del lenguaje lo que es. Si es así, son buenas noticias.

Breve historia de ECMAscript 4

La última versión mayor de Javascript se liberó en 1999, eso son 9 años sin actualizar el lenguaje. Durante estos últimos años, el grupo detrás de ECMAscript 4 ha estado muy activo. Las principales características de la nueva versión pretenden preparar el lenguaje para crear proyectos de envergadura dado que desde el principio ha estado orientado a crear programas cortos que interactuen sólo con el navegador (a través del DOM). Aunque chocaba el nulo interés que mostraba Microsoft por participar de los avances. Justo cuando estaban a punto de aprobar las especificaciones definitivas, Chris Wilson de Microsoft, se desmarcó de los avances y hubo una discusión bastante fuerte entre él y Brendan Eich, el creador del lenguaje, principalmente motivada porque Microsoft sólo dio señales de vida al final y para discrepar del trabajo de los demás. Microsoft y Yahoo! optaron por escindir la corriente principal y respaldar lo que se conoce como ECMAscript 3.1, mucho menos radical y más acorde con sus intereses. Se llegó a un punto en el que el grupo del 3.1 necesitaba añadir características que eran incompatibles con la futura versión 4, por lo que el tema estaba cada vez más caliente.

Resig hace referencia a la reciente reunión en Oslo del TC39 y a las palabras de Brendan Eich en las que resume la reunión de Oslo y el acuerdo de unión entre los dos grupos con los siguientes puntos (lo que se llamó ECMAScript Harmony):
  1. Enfocar el trabajo en ECMAscript 3.1 por todas las partes y buscar dos implementaciones interoperables para el año que viene.
  2. Colaborar en el siguiente paso más alla de ECMAscript 3.1, que incluirá extensiones sintácticas pero que será más modesto que ECMAscript 4 en cuanto a innovación sintáctica y semántica.
  3. Algunas propuestas de ECMAscript 4 han sido descartadas por inadecuadas para la web, y están fuera de la mesa para siempre: packages, namespaces y enlazado temprano. Esta conclusión es clave para Harmony.
  4. Otras metas e ideas de ECMAscript 4 están siendo reformuladas para mantener el consenso en el comité; estas incluyen la noción de clases basadas en los conceptos existentes de ES3 combinadas con las extensiones propuestas en ES 3.1.
En definitiva, todos los cambios son conservadores y, en mi opinión, muy acertados (y no soy el único) al alejarse de características extrañas para los programadores de Javascript y que parecen venir de programadores de aplicaciones que generan código de salida en Javascript y que quieren más potencia en el navegador pero que no programan directamente en el lenguaje.

Características en ES3.1

  • Getters y Setters para ejecutar cuando se lee o escribe una propiedad de una clase
    class Programador {
      var _nombre;
      function get nombre(){ return _nombre; }
      function set nombre(valor){
        _nombre = valor + " Resig";
      }
    }
    var p = new Programador;
    p.nombre = "John";
    alert( p.nombre ); // "John Resig"
    
  • Catch-All o método para capturar todas las llamadas a miembros de una clase
    dynamic class Programador {
      meta function get(nombre) { ... }
      meta function set(nombre, valor) {
        alert("Poniendo " + nombre + " a " + valor);
      }
    }
    var p = new Programador
    p.nombre = "John"; // alert("Poniendo name a John");
    
  • Catch-All o método para capturar todas las llamadas a miembros de una clase
  • Object.getPrototypeOf(obj) para obtener el prototipo de una clase

Características en ES4

  • Getters y Setters para ejecutar cuando se lee o escribe una propiedad de una clase
    class Artista {
      function pintar() { alert("Pintando!"); }
    }
    class Disenyador extends Artista {
      override function pintar() {
        alert("Disenyando!");
      }
    }
    var d = new Disenyador
    d.pintar(); // alert("Disenyando!");
    
    // los métodos 'final' no pueden solaparse
    class Artista {
      final function pintar() {alert("Pintando!");}
    }
    class Disenyador extends Artista {
      // ERROR: No se puede solapar el método 'pintar'
      override function pintar() {
        alert("Disenyando!");
      }
    }
    
    // las clases 'final' no pueden heredarse
    final class Artista {
      function pintar() { alert("Pintando!"); }
    }
    // ERROR: No se puede heredar de 'Artista'
    class Disenyador extends Artista {
      ...
    }
    
  • Metaclases o métodos estáticos. Pueden llamarse sin instanciar la clase
    // proveen funciones y propiedades globales sobre un objeto class
    class Usuarios {
      static function encontrar( nombre ) {
        // ...
      }
    }
    // Nótese que no se instancia con (new Usuarios()).encontrar( "John" )
    Usuarios.encontrar( "John" ); 
    
  • Interfícies, verifican que una clase implementa los métodos de otra
    interface Artista {
      function pintar();
    }
    class Disenyador implements Artista {
      function pintar() { alert("Disenyando!"); }
    }
    var d = new Disenyador();
    if ( d is Artista ) alert("Los Disenyadores son Artistas!");
    
  • Tipos Especificación de tipos:
    var nombre : string = "John";
    let x : double = 5.3;
    function stuff( x: int, obj: Object ) : boolean {} // Sólo devuelve boolean
    function cada( este: Array, valor: int ) { // sólo acepta Arrays como primer parámetro
      for ( var i = 0; i < this.length; i++ )
        alert( this[i] );
    }
    cada.call( [0,1,2], 3 ); // alert(0); alert(1); alert(2);
    cada.call( {a: "b"}, 4); // ERROR al ser un objeto el primer parámetro
    function stuff( nombre, ...valores ){ // la sintaxis ...valores indica que el resto de parámetros se guardarán en la variable valores
      alert( valores.length );
    }
    stuff( "John", 1, 2, 3, 4 ); // alert( 4 ); o sea, la cantidad de parámetros que han entrado como valores ~= [1,2,3,4]
    var test : (string, int, double) = "test"; // test sólo acepta cadenas, o números
    test = 3;
    test = false; // ERROR
    type CualquierNumero = (byte, int, double, decimal, uint);
    var test : CualquierNumero = 3
    
    // las dos siguientes líneas son equivalentes
    var test2 : * = "test";
    var test2 = "test";
    type Punto = { x: int, y: int }; // así defino el nuevo tipo Punto
    var p : Punto = { x: 3, y: 24 };
    
    // evitar aceptar null
    var nombre : String! = "John"; // previene que las variables acepten valores null
    nombre = null; // ERROR
    function test( name: String? ) { // parámetro obligatorio
      alert( name );
    }
    class Usuario {
      var nombre : string!; // propiedad que debe inicializarse obligatoriamente
      var apellidos : string!;
      function Usuario( n, l ) : nombre = n, apellidos = l {
        // ...
      }
    }
    
    // uso de like
    if ( { x: 3, y: 5 } like Punto ) alert( "Eso parece un punto" );
    function cada( a: like { length: uint } ) { // recorre lo que se parezca a array
      for ( var i = 0; i < a.length; i++ ) alert( a[i] );
    }
    

Tamarin, V8 y ScreamingMonkey

Tamarin es una máquina virtual de Javascript 2 que Adobe ha realizado para el plugin de Flash (Actionscript). Aún se desconoce si Adobe ofrecerá a través de su ubicuo Flash la opción de ejecutar Javascript 2 en todos los navegadores. En caso de que no lo haga, el proyecto Screaming Monkey es un plugin abierto para Internet Explorer (basado en Tamarin) que permitirá utilizar Javascript 2 en ese navegador en el caso de que Microsoft mantenga su intención de no pasar de ECMAscript 3.1.

Finalmente, el último motor aparecido es el de Google Chrome. V8 ha sido la primera versión publicada y activada en un navegador de la siguiente generación de intérpretes de alto rendimiento. Sin duda, el lenguaje promete.

Publicar un comentario en la entrada

Últimos links en indiza.com