Javascript closures

Se facemos uso da programación orientada a obxectos en javascript é habitual botar man das clausuras para manexar os eventos HTML por medio dos métodos do obxecto. As clausuras javascript non deixan de ser funcións javascript pero que se executan baixo un contexto que lle especificamos.

Partindo da seguinte clase queremos facer que cando se prema nunha ligazón o evento onclick sexa manexado polo método setText, que establecerá o valor da propiedade text da clase Link.

var Link = function() {
    this.text = null;
 
    this.setText = function(a) {
        this.text = a.innerHTML; 
        console.log(this); // Link
     };
};

O código HTML coa ligazón que manexará o evento onclick:

   <a id="linky" href="#nada">Enlace</a>

Para poder "ligar" o evento onclick co método Link#setText() será preciso crear unha clausura que lle indique ao método que se ten que executar no contexto de Link e non do HTMLElement. Para que iso imos extender o prototype do obxecto Function e engadirlle un método bind que o que faga sexa devolver unha clausura que se execute baixo o contexto dun obxecto (context).

Function.prototype.bind = function(obj) {
    var fn = this, args = Array.prototype.slice.call(arguments), context = args.shift();
 
    return function() {
        return fn.apply(context, args.concat(Array.prototype.slice.call(arguments)));
    };
};
 

Deste modo poderemos executar calquera función baixo o contexto desexado, no noso caso queremos obxectoLink.setText.bind(obxectoLink)

Agora soamente queda instanciar a clase Link e indicar que o evento onclick será manipulado pola clausura, a que ademais tamén lle pasamos a maiores a referencia ao obxecto HTML (segundo parámetro).

var enlace = new Link();
var $ = document.getElementById; // atallo
$('linky').onclick = enlace.setText.bind(enlace, $('linky'));

 

Última actualización 2012-08-15
2:56 AM (Europe/Madrid)
Data de creación 2009-11-27
11:00 PM (Europe/Madrid)
Closures are one of the most powerful features of ECMAScript (javascript) but they cannot be property exploited without understanding them.
javascript