Reputation: 6999
I am using the javascript inheritance helper provided here: http://ejohn.org/blog/simple-javascript-inheritance/
I have the following code, and I have problem accessing the inherited property or function from a closure within a subclass as illustrated below. I am new to OOP javascript code and I appreciate your advice. I suppose within the closure, the context changes to JQuery (this variable) hence the problem. I appreciate your comments.
Thanks, -A
PS - Using JQuery 1.5
var Users = Class.extend({
init: function(names){this.names = names;}
});
var HomeUsers = Users.extend({
work:function(){
// alert(this.names.length); // PRINTS A
// var names = this.names; // If I make a local alias it works
$.map([1,2,3],function(){
var newName = this.names.length; //error this.names is not defined.
alert(newName);
});
}
});
var users = new HomeUsers(["A"]);
users.work();
Upvotes: 1
Views: 241
Reputation: 11354
this
in the inner function
function(){
var newName = this.names.length;
alert(newName);
}
is not the same as this
in the outer function.
work: function(){
$.map([1,2,3],function(){
var newName = this.names.length;
alert(newName);
});
}
There are many ways that people work around this:
this
as another variablework: function(){
var that = this;
$.map([1,2,3],function(){
var newName = that.names.length;
alert(newName);
});
}
As you see, that
is being used instead of this
.
$.proxy
work: function(){
$.map([1,2,3],$.proxy(function(){
var newName = this.names.length;
alert(newName);
}, this));
}
What $.proxy
does is it creates another function that calls the function you passed in (in this case, the inner function), but explicitly set the context of the function (this
) to the second arguments.
work: function(){
$.map([1,2,3],function(){
var newName = this.names.length;
alert(newName);
}.bind(this));
}
It works just like jQuery's $.proxy
, but in this one, you call the bind
method of the function.
It isn't supported on all browsers, but there is a JavaScript implementation of Function.prototype.bind on MDC. You can use it.
this
in a confusing keyword, and if you want to learn more about this
, then look at this.
Upvotes: 3
Reputation: 43380
The this
variable is not like the others. Normal variables are always available to their child scopes, but this
is, by default, set to the global window
object when a function is called:
alert(this.names); # Works; this == yourObject
$.map([1,2,3],function(){
alert(this.names); # Doesn't work; this == window.
});
The documentation for jQuery.map() confirms this:
this
will be the global window object.
Thus, the solution is to set another variable to this
so it will be available in the child scope:
var that = this;
$.map([1,2,3],function(){
alert(that.names);
});
I recommend viewing Douglas Crockford's presentation Function the Ultimate, in which he shows all sorts of crazy things you can do with functions and objects in JavaScript.
Upvotes: 0