this thing almost works:
function myClass(url) {
this.source = url;
this.rq = null;
this.someOtherProperty = "hello";
// open connection to the ajax server
this.start = function() {
if (window.XMLHttpRequest) {
this.rq = new XMLHttpRequest();
if (this.rq.overrideMimeType)
this.rq.overrideMimeType("text/xml");
} else
this.rq = new ActiveXObject("Microsoft.XMLHTTP");
try {
this.rq.onreadystatechange = connectionEvent;
this.rq.open("GET", this.source, true);
this.rq.send(null);
this.state = 1;
} catch (err) {
// some error handler here
}
}
function connectionEvent() {
alert("i'm here");
alert("this doesnt work: " + this.someOtherProperty);
}
} // myClass
so it’s nothing more than having the XMLHttpRequest object as a member of my class, instead of globally defined, and invoking it in the traditional way. however, inside my connectionEvent callback function, the meaning of “this” is lost, even though the function itself is scoped inside myClass. i also made sure that the object that i instantiate from myClass is kept alive long enough (declared global in the script).
in all the examples of using javascript classes that i saw, “this” was still available inside the inner functions. for me, it is not, even if i take my function outside and make it a myClass.prototype.connectionEvent. what am i doing wrong? thank you.
The reason it’s not working is that in Javascript,
thisis defined entirely by how a function is called, not where it’s defined. This is different than some other languages.To have
thismean what you expect, you’d have to ensure that explicitly by “binding” it:There’s more information about
thismanagement in this blog post, but basically: When a function is called without any particular effort made to setthis,thiswithin the function will always be the global object (window, on browsers). There are two ways to setthiswhen making a call:Function#call(orFunction#apply) as I did above, passing in the object reference to use asthisas the first parameter. That calls the function and setsthisto whatever you passed in. The difference between#calland#applyis how you supply further arguments to pass into the function. With#callyou supply them as further arguments to the#callcall (e.g.func.call(thisArg, arg0, arg1, arg2)), whereas with#applyyou supply them as an array in the second argument (func.apply(thisArg, [arg0, arg1, arg2])).startproperty), calling it by using the object instance, a dot, and the property name (this.start()orfoo.start(), etc.) will call the function and setthisto the object instance within the call. So the dotted notation does two entirely distinct things: Looks up the property and finds a function as its value, and calls the function such thatthisis set to the object during the call. Literally it’s like:var f = obj.func; f.call(obj).Slightly off-topic, but: Barring a really good reason to, I wouldn’t reinvent this wheel. There are lots of libraries out there to simply XHR calls. jQuery, Prototype, Closure, and nearly all the rest.