Event handlers automatically point the this
keyword to the element the event is firing on. ECMA-262 5th Edition attempts to combat situations like this by implementing an old technique of "binding" a function to a specific object:
// From Prototype.js
if (!Function.prototype.bind) { // check if native implementation available
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments),
object = args.shift();
return function(){
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
};
};
}
Usage:
function MyClass(){
this.init = function(input){
this.input.onkeyup = (function(){
this.change();
}).bind(this);
}
}
The ECMAScript implementation is the same as the PrototypeJS implementation (for which the code is above).
You could also implement it on a per-class basis:
function MyClass(){
this.bind = function(){
var args = Array.prototype.slice.call(arguments),
self = this,
fn = args.shift();
return function(){
return fn.apply(self,
args.concat(Array.prototype.slice.call(arguments)));
};
};
this.init = function(input){
this.input.onkeyup = this.bind(function(){
this.change();
});
}
}
The archaic ;-) option is to just store a reference to this
outside of the function:
function MyClass(){
var self = this;
this.init = function(input){
this.input.onkeyup = function(){
self.change();
}
}
}