2010-05-11 13 views
8

मैं कुछ अजाक्स का javascript ऑब्जेक्ट .:XMLHttpRequest: कैसे संदर्भ रखने के लिए "इस"

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 
     } 
     } 
    } 
}; 

onreadystatechange समारोह के अंदर अंदर से कॉल करें, यह मुख्य उद्देश्य के लिए अब और का उल्लेख नहीं करता करने के लिए , इसलिए मुझे इस तक पहुंच नहीं है। foo। हो सकता है कि मैं XMLHttpRequest घटनाओं के अंदर मुख्य ऑब्जेक्ट का संदर्भ रखूं?

उत्तर

7

सबसे सरल दृष्टिकोण एक स्थानीय चर पर this का मूल्य स्टोर करने के लिए आमतौर पर है:

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 
     } 
     } 
    }; 
    } 
}; 

मैं भी संदेह है कि आपके myObject पहचानकर्ता वास्तव में है एक constructor function (यदि आप एक prototype संपत्ति बताए जाते हैं)।

यदि ऐसा है तो सही constructor संपत्ति शामिल करना न भूलें (क्योंकि आप पूरे prototype को प्रतिस्थापित कर रहे हैं), जो कि केवल कन्स्ट्रक्टर के संदर्भ में है।

हो सकता है कि विषय से हटकर इस मुद्दे पर लेकिन पढ़ने के लिए सिफारिश की:

4

एक अन्य सरल उपाय यह करने के लिए अपने onreadystatechange समारोह बाध्य करने के लिए है। bind- फ़ंक्शन को अनिवार्य रूप से सीएमएस के उत्तर (यानी, बंद करने के लिए मूल्य जोड़ना) जैसा ही होता है, लेकिन bind इसे पारदर्शी तरीके से करता है: instance चर सेट करने के बजाय आप this का उपयोग करते रहें। यहाँ

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)); 
    }; 
} 

और कैसे आप इसे अपने कोड में उपयोग कर सकते हैं:

यहाँ एक Function#bind कार्यान्वयन है अगर अपने कोड बेस एक को शामिल नहीं करता

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

मैं दृढ़ता से जांच करने के लिए सिफारिश करेंगे यदि इसे बनाने से पहले 'Function.prototype.bind' विधि मौजूद है, क्योंकि यह ईसीएमएस्क्रिप्ट 5 वें संस्करण मानक का हिस्सा है और इसे सभी प्रमुख ब्राउज़र विक्रेताओं द्वारा कार्यान्वित किया जा रहा है, जल्द ही एक मूल कार्यान्वयन उपलब्ध होगा और आप नहीं चाहते हैं इसे अपने आप से ओवरराइड करें: [वेबकिट] (https: // bugs.webkit.org/show_bug.cgi?id=26382), [मोज़िला] (https://bugzilla.mozilla.org/show_bug.cgi?id=429507), [Google V8] (http://code.google .com/पी/v8/मुद्दों/विस्तार? id = 384)। – CMS

संबंधित मुद्दे