středa 4. března 2009

JavaScript a closures

Dnes jsem narazil na zajímavý problém s uzávěry (closures) v JavaScriptu:

var b = new Array();
for (var x=0; x<4; x++) {
 b[x] = function() {
  alert(x);
 };
}
b[2]();

Pokud laskavý čtenář předpokládá, že volání vypíše "2", je stejně naivní jako já. Kód vypisuje pro všechny volání "4".
Problém spočívá v tom, že při volání volání uzávěru se (pro nás Java programátory naprosto nepochopitelně :) použije zásobník, který existoval při vytvoření uzávěru.
Jak z toho ven radí Otec Fura: já jsem použil způsob, který použitím Data Transfer Objectu vynutí vykopírování proměnné z lokálního kontextu:

var c = new Array();
for (var x=0; x<4; x++) {
 var Dto = function() {
  var value = x;
  this.getValue = function() { 
   alert(value);
  };
 }
 c[x] = new Dto().getValue;
}
c[2]();

Žádné komentáře:

Okomentovat