2010-05-11 19 views
8

Bazı Ajax onreadystatechange fonksiyonu içinde bir javascript nesne .:XMLHttpRequest: referansı tutmak için nasıl "bu"

myObject.prototye = { 
    ajax: function() { 
    this.foo = 1; 

    var req = new XMLHttpRequest(); 
    req.open('GET', url, true); 
    req.onreadystatechange = function (aEvt) { 
     if (req.readyState == 4) { 
     if(req.status == 200) { 
      alert(this.foo); // reference to this is lost 
     } 
     } 
    } 
}; 

içinden arama yapmak, bu artık ana nesne ifade etmez etmek bu yüzden buna erişemiyorum. Ho referansı XMLHttpRequest olayları içindeki ana nesneye taşıyabilir miyim?

cevap

7

en basit yaklaşım, yerel bir değişkeni this değerini depolamak için genellikle:

myObject.prototype = { 
    ajax: function (url) { // (url argument missing ?) 
    var instance = this; // <-- store reference to the `this` value 
    this.foo = 1; 

    var req = new XMLHttpRequest(); 
    req.open('GET', url, true); 
    req.onreadystatechange = function (aEvt) { 
     if (req.readyState == 4) { 
     if (req.status == 200) { 
      alert(instance.foo); // <-- use the reference 
     } 
     } 
    }; 
    } 
}; 

Ben senin myObject tanımlayıcı gerçekten olması da şüpheli bir constructor function (bir prototype özelliği atıyorsunuz).

Böyle bir durumda, constructor özelliği (prototype öğesinin tamamını değiştirdiğiniz için) eklemeyi unutmayın, bu yalnızca kurucunun bir referansıdır.

Belki konu dışı bu konuya ama okumayı tavsiye:

4

bir diğer basit bir çözüm bu şekilde onreadystatechange fonksiyonunu bağlamaktır. bind - işlev aslında CMS'nin cevabındakiyle aynı şeyi yapar (yani, değeri kapanmaya ekler), ancak bind bunu saydam bir şekilde yapar: instance değişkenini ayarlamak yerine this kullanmaya devam edersiniz. İşte

kodunuzu tabanı biri içermiyorsa bir Function#bind uygulamasıdır:

Function.prototype.bind = function(obj) { 
    var __method = this; 
    var args = []; for(var i=1; i<arguments.length; i++) args.push(arguments[i]); 
    return function() { 
     var args2 = []; for(var i=0; i<arguments.length; i++) args2.push(arguments[i]); 
     return __method.apply(obj, args.concat(args2)); 
    }; 
} 

Ve burada kodunuzda kullanabilirsiniz nasıl:

myObject.prototype = { 
    ajax: function() { 
    this.foo = 1; 

    var req = new XMLHttpRequest(); 
    req.open('GET', url, true); 
    req.onreadystatechange = function (aEvt) { 
     if (req.readyState == 4) { 
     if(req.status == 200) { 
      alert(this.foo); // reference to this is *kept* 
     } 
     } 
    }.bind(this) // <- only change 
    } 
}; 
+0

şiddetle kontrol etmek öneriyoruz "Function.prototype.bind" yöntemi, oluşturmadan önce var ise, ECMAScript 5. Baskı Standardının bir parçası olduğu ve tüm büyük tarayıcı satıcıları tarafından uygulandığı için, yakında yerel bir uygulama mevcut olacak ve kendi başınıza geçersiz kılın: [WebKit] (https: // bugs.webkit.org/show_bug.cgi?id=26382), [Mozilla] (https://bugzilla.mozilla.org/show_bug.cgi?id=429507), [Google V8] (http://code.google .com/p/v8/sorunlar/detay? id = 384). – CMS

İlgili konular