Prototype mintadarabok 3

prototypeAz egyik legzavarbaejtőbb JavaScript viselkedés a függvényekben használat this tulajdonsághoz kapcsolódik. Ma ezt küldjük a műtőasztalra.
Amikor a JavaScript kódunk lefutatt egy függvényt, akkor a függvényben lévő this hivatkozás akkor fog a függvényhez kötődni amikor az elkezd futni, nem pedig akkor amikor a függvényt definiáljuk. Alapértelmezés szerint egy objektumon kívüli függvény a window objektumhoz van kötve, mivel a JavaScript esetében a window objektum testesíti meg a globális futási környezetet.

A probléma

Ha a függvényt úgy hívjuk meg, nem hivatkozunk a hozzá tartozó objektumhoz akkor elveszítjük a kötést. A legegyszerűbb példa erre amikor a függvényt egy másik függvénynek adunk át paraméterül.

var tesztObjektum = {
  nev: 'Ez a teszt objektum' ,
  getNev: function() {
    return this.nev;
    }
  };
window.nev = '' ;
tesztObjektum.getNev();      // -> 'Ez a teszt objektum'

function tesztFuggveny(fgv) {
  return fgv();
  }

tesztFuggveny(tesztObjektum.getNev)      // -> ''

window.nev = 'A window objektum' ;
tesztFuggveny(tesztObjektum.getNev);      // -> 'A window objektum'

Ez így már gondolom mindenkinek érdekessé teszi a problémát.

bind

Szerencsére a prototype egyből tálcán kínálja a megoldást a bind és a bindAsEventListener függvényekkel.

tesztFuggveny(tesztObjektum.getNev.bind(tesztObjektum));
// -> 'Ez a teszt objektum'

Ha egy ciklusban szeretnénk használni a bind függvényt, akkor jobb ha a kötést csak egyszer hozzuk létre.

//ne így, mert ez minden egyes iterációnál új kötést hoz létre!
for (var i = 1; i < 10; ++i)
  tesztFuggveny(tesztObjektum.getNev.bind(tesztObjektum));

//hanem így
var bindeltGetNev = tesztObjektum.getNev.bind(tesztObjektum);
for (var i = 1; i < 10; ++i)
  tesztFuggveny(bindeltGetNev);

bindAsEventListener

Ha szeretnénk eseménykezelőként használni a meghívott függvényt akkor a bindAsEventListener függvényt kell használnunk. Ez annyiban különbözik a bind-től, hogy biztosítja, hogy a meghívott függvény első paramétereként átadódjon maga az esemény objektum.

var tesztObjektum = { nev: 'És íme: ' };

function kattKezelo(e) {
  var tag = Event.element(e).tagName.toLowerCase();
  var data = $A(arguments);
  data.shift();
  alert(this.nev + 'Kattintás a ' + tag + '-on További függvény paraméterek: ' + data.join(', '));
}

Event.observe(document.body, 'click', kattKezelo.bindAsEventListener(tesztObjektum, 1, 2, 3));

A függvény azt fogja eredményezni, hhogy ha valahová kattintunk a böngészőben, akkor ki fogja írni, hogy melyik DOM elemre kattintottunk, valamint további paraméterként megjeleníti, hogy 1, 2, 3. Vagyis nem vesztette el a csatolást, megkapta az eseményt és a többi paramétert is.

2 thoughts on “Prototype mintadarabok 3

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöljük.