Reputation: 12764
I am trying to access an object's member variables from inside a method that is passed as a callback which is fired during a filereader event.
I have whipped together the code below just to try and convey my point. It appears that 'this' becomes the filereader instead of the object at the point of call. Is there a way to have the finishLoading be able to access the objects variables?
I would like to make sure that the callbacks are tailored to the object, otherwise I would have just defined them as static functions outside the class.
function myClass(newName)
{
this.name = newName;
this.m_fileReader = new FileReader();
this.finishedLoading =
function(param1)
{
alert(this.name);
};
this.m_fileReader.addEventListener('loadend',
this.callback_finishedLoading,
false);
}
var instance = new myClass('timmy');
var instance2 = new myClass('joe');
Upvotes: 1
Views: 129
Reputation: 339816
You need the .bind
function:
this.m_fileReader.addEventListener('loadend',
this.callback_finishedLoading.bind(this),
false);
The .bind
function will take the passed parameter, and call the original function with that parameter as its this
instead of whatever value the browser tried to supply.
Alternatively, just create your own alias to this
and wrap your call in an anonymous function:
var self = this;
this.m_fileReader.addEventListener('loadend', function(ev) {
self.callback_finishedLoading(ev)
}, false);
The latter is mostly what .bind
does behind the scenes, but does have the advantage that it'll work on pre-ES5 browsers without a shim.
Upvotes: 4
Reputation:
You can make your constructor implement the EventListener interface, like this:
function myClass(newName) {
this.name = newName;
this.m_fileReader = new FileReader();
this.m_fileReader.addEventListener('loadend', this, false);
}
myClass.prototype.handleEvent = function(event) {
return this[event.type] && this[event.type](event)
}
myClass.prototype.loadend = function(event) {
alert(this.name);
};
var instance = new myClass('timmy');
var instance2 = new myClass('joe');
I renamed the finishedLoading
to loadend
, and put it on the .prototype
of the constructor. Then I added a .handleEvent
method to the .prototype
.
Finally in the constructor, we don't pass a function at all. Instead just pass the this
, which is your myClass
instance.
I removed your param1
because it was unclear how that was to be used. If it needs to receive some value from other invocations, then you can create a separate finishedLoading
method on the .prototype
, and have the .loadend()
method invoke it.
Upvotes: 1
Reputation: 2804
this
is relative to the context. Every time you open a new block {} it changes to the current block context. Save this
to another variable before calling the callback function.
Upvotes: 0