Ver Mensaje Individual
  #1 (permalink)  
Antiguo 20/01/2014, 13:50
Pantaláimon
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Sobrescribir palabras clave como métodos

Buenas,

Estos días, para practicar un poco con los conocimientos de Javascript que he ido aprendiendo, he creado una clase DOMAutomat que va modificando elementos del DOM a ciertos intervalos de tiempo y en función de un objeto que contiene las instrucciones. Dicho objeto representa unas instrucciones similares al ensamblador por tener saltos condicionales e incondicionales. Luego he creado otra clase Compiler que a través de llamadas a métodos, va construyendo el objeto que luego recibirá DOMAutomat. Y ahí viene el problema. Para que esos métodos sean sugerentes con lo que hacen les he dado nombres como while, if o else que son palabras clave. Aquí dejo el código de interés:

Código Javascript:
Ver original
  1. cc
  2.     .var({
  3.         '$cells'  : cells    ,
  4.         '$i'      : 0        ,
  5.         '$j'      : undefined,
  6.         '$prev'   : undefined,
  7.         '$cur'    : undefined,
  8.         '$flag'   : true     ,
  9.         '$bgClass': 'bg-red'
  10.     })
  11.     .action([
  12.         // accion nula
  13.     ])
  14.     .while( "$i < 4" )
  15.         .calc( "$j = 0" )
  16.         .while( "$j < 4" )
  17.             .calc( "$cur = $cells[$i][$j]" )
  18.             .if( "$flag" )
  19.                 .action( [
  20.                     ["$prev", removeClass, ["$bgClass"] ],
  21.                     ["$cur" , addClass   , ["$bgClass"] ]
  22.                 ])
  23.                 .if( "$cur.classList.contains('bg-blue')" )
  24.                     .action([
  25.                         ["$cur", removeClass, ["$bgClass"] ]
  26.                     ])
  27.                     .calc(
  28.                         "$bgClass = $bgClass === 'bg-red' ? 'bg-green' : 'bg-red';" +
  29.                         "$flag = false;"
  30.                     )
  31.                     .action([
  32.                         ["$cur", addClass, ["$bgClass"] ]
  33.                     ])
  34.                 .end()
  35.                 .calc( "$prev = $cur" )
  36.             .else()
  37.                 .calc( "$flag = true" )
  38.             .end()
  39.             .calc( "++$j" )
  40.         .end()
  41.         .calc( "++$i" )
  42.     .end()
  43.     .action([
  44.         ["$prev", removeClass, ["$bgClass"] ]
  45.     ]);
  46.     console.log( cc.code );
  47.  
  48.     // crea un autamata que ejecuta una acción cada segundo
  49.     var domAutomat = new DOMAutomat(1000);
  50.     // asigna el codigo al automata
  51.     domAutomat.setCode( cc.code );
  52.     // pone en ejecución el automata
  53.     domAutomat.run();

Y aquí el enlace con todo el código y el resultado:
http://jsfiddle.net/jefebrondem/ny7Ky/

Tengo dos dudas. La principal es si sobrescribir métodos con palabras clave lo soporta el estándar. Pues, por ejemplo, a mi chrome me lo permite pero puedo asegurar que cualquier navegador que siga el estándar me lo permitirá. No he encontrado información al respecto.

La otra duda es más de diseño, yo en este caso me he visto inevitablemente forzado a usar el constructor Function para ganar en expresividad. Antes de usar el constructor Function el código con while's e if's lo simulaba con un objeto literal quedando algo de este estilo:
Código Javascript:
Ver original
  1. var code = [
  2.         { 'var' : {
  3.             'i'      : 0        ,
  4.             'j'      : undefined,
  5.             'prev'   : undefined,
  6.             'cur'    : undefined,
  7.             'flag'   : true     ,
  8.             'bgClass': 'bg-red'
  9.         }},
  10.         { 'action': function() { return [
  11.             //acción nula
  12.         ]}},
  13.         { 'while': [ function(){ return this.i < 4; },
  14.             function(){
  15.                 this.j = 0;
  16.             },
  17.             { 'while' : [ function(){ return this.j < 4; },
  18.                 function(){
  19.                     this.cur = cells[this.i][this.j];
  20.                 },
  21.                 { 'if': [ function(){ return this.flag; },
  22.                     { 'action': function() { return [
  23.                         [this.prev, removeClass, [this.bgClass] ],
  24.                         [this.cur , addClass   , [this.bgClass] ]
  25.                     ]}},
  26.                     { 'if': [ function(){ return this.cur.classList.contains('bg-blue'); },
  27.                         { 'action': function() { return [
  28.                             [this.cur, removeClass, [this.bgClass] ],
  29.                         ]}},
  30.                         function(){
  31.                             this.bgClass = this.bgClass === 'bg-red' ? 'bg-green' : 'bg-red';
  32.                             this.flag = false;
  33.                         },
  34.                         { 'action': function() { return [
  35.                             [this.cur, addClass, [this.bgClass] ],
  36.                         ]}},
  37.                     ]},
  38.                     function(){
  39.                         this.prev = this.cur;
  40.                     }
  41.                 ],'else': [
  42.                     function(){
  43.                         this.flag = true;
  44.                     }
  45.                 ]},
  46.                 function(){
  47.                     ++this.j;
  48.                 },
  49.             ]},
  50.             function(){
  51.                 ++this.i;
  52.             }
  53.         ]},
  54.         { 'action': function() { return [
  55.             [this.prev, removeClass, [this.bgClass] ]
  56.         ]}}
  57.     ]
http://jsfiddle.net/jefebrondem/aexE7
De esta manera no he usado el constructor Function, pero el código es más dicifil de escribir y, con ello, más propenso a escribirlo mal.
¿Alguien sabría de alguna manera más simple de representación sin tener que echar mano al contructor Function o a eval?

Un saludo y gracias.
__________________
github.com/xgbuils | npm/xgbuils