Getters, Setters y vinculación de objetos

Recientemente he estado leyendo algunos artículos de javascript en los que se explicaban las bondades de los getters y los setters y cómo podemos utilizarlos para darles más funcionalidad a nuestras clases.

Un Ejemplo sencillo sería el siguiente:

  var MiClase = function() {
    var _value = 0;
    var clase = {
      get value() {
         return _value;
      },
      set value(v) {
         _value = v;
      },
    };
    return clase;
  };

Lo definido arriba es equivalente a esto:

  var MiClase = function() {
    this.value = 0;
  };

Pero claro, ¿para qué hacer algo más complicado si no se obtiene ningún beneficio?, la respuesta está en que al ser los getters y los setters funciones, podemos añadir más acciones dentro de estas a parte de las de devolución y asignación de variables.

Uno de los usos que se le puede dar es vincular un objeto que creemos a través de la clase con un objeto DOM, como por ejemplo una caja de texto:

  var MiClase = function(t) {
    var _value = 0,
        _obj = document.getElementBy(t);

    var clase = {
      get value() {
         return _value;
      },
      set value(v) {
         _value = v;
         _obj.value = v;
      },
    };

    _obj.addEventListener('blur', function() {
      clase.value = this.value;
    }, false);

    return clase;
  };

  var miObjeto = new MiClase('micaja');

Con el código de arriba conseguimos vincular el objeto miObjeto con la caja de texto de identificador micaja, de manera que siempre que introduzcas algo en la caja de texto se actualizará la propiedad value del objeto miObjeto y viceversa.

Podemos complicar un poco más la definición de la clase para añadir vinculación entre objetos, es decir, yo quiero vincular dos objetos a través de una propiedad de uno de ellos, de manera que cuando actualice la propiedad en el objeto origen en el objeto destino se realicen una serie de acciones. Para todo esto, la clase quedaría de la siguiente manera:

var MiClase = function(t) {
    var _value = 0,
        _obj = document.getElementBy(t),
        _binds = {};

    var clase = {
      get value() {
         return _value;
      },
      set value(v) {
         _value = v;
         _obj.value = v;
         var self = this;
         _binds['value'] && _binds['value'].forEach(function(e) {
           e.func.apply(e.obj, [self]);
         });
      },
      bind: function(v, o, f) {
        _binds[v] || (_binds[v] = []);
        _binds[v].push({
          obj: o,
          func: f
        });
      }
    };

    _obj.addEventListener('blur', function() {
      clase.value = this.value;
    }, false);

    return clase;
  };

Lo que hemos hecho ha sido añadir un objecto que contiene un array de vinculaciones, _binds, y una función bind que nos permite asociar objetos. También hemos añadido en el setter la ejecución de las funciones de vinculación que pueda tener el objeto pasando como parametro el propio objeto para que puedan interactuar con él.

Ahora el código para realizar las vinculaciones:

  var miObjeto1 = new MiClase('caja1');
  var miObjeto2 = new MiClase('caja2');

  miObjeto1.bind('value', miObjeto2, function(e) {
    this.value = e.value + '(copia)';
  });

Con el código de arriba lo que hemos hecho ha sido vincular las cajas de texto caja1 y caja2 con los objetos miObjeto1 y miObjeto2 respectivamente y después hemos vinculados los dos objetos entre sí por medio de la propiedad value de miObjeto1 de manera que cuando ésta cambie se llamará a la función de vinculación. En este ejemplo sencillo, cada vez que se cambia la propiedad value de miObjeto1 se le asigna a la propiedad value de miObjeto2 el mismo valor más el texto “(copia)”.

Dentro de la función de vinculación, this hace referencia al objeto destino, en nuestro ejemplo, miObjeto2 y el parámetro e hace referencia al objeto origen, en el ejemplo, miObjeto1.

Referencias
JavaScript getters and setters: varying approaches
Javascript getters and setters for dummies?
Working with objects

Un comentario en “Getters, Setters y vinculación de objetos

Los comentarios están cerrados.