I have a class method and a closure within this method. How I can access to class member from closure?
Person = function(x) {
this.x = x;
}
Person.prototype = {
myMethod: function() {
$('#myBtn').click( function() {
// how to access to this.x? the this reference points in another context
});
}
}
I have a class method and a closure within this method. How I can access to class member from closure?
Person = function(x) {
this.x = x;
}
Person.prototype = {
myMethod: function() {
$('#myBtn').click( function() {
// how to access to this.x? the this reference points in another context
});
}
}
Share
Improve this question
edited Sep 1, 2013 at 18:51
WeleTo
asked Sep 1, 2013 at 18:40
WeleToWeleTo
20.6k56 gold badges176 silver badges290 bronze badges
4 Answers
Reset to default 9Use of Function.prototype.bind
will help you here
Person = function(x) {
this.x = x;
}
Person.prototype.myMethod = function() {
$('#myBtn').click(function() {
this.x;
}.bind(this));
};
You can use some better separation of code here too
Person = function(x) {
this.x = x;
};
Person.prototype.myMethod = function {
$('#myBtn').click(this.clickHandler.bind(this));
};
Person.prototype.clickHandler = function(event) {
console.log(this.x);
};
Note if you want to support older browsers, check out es5-shim
EDIT
I'm revisiting this after ~6 months and I would probably write the above code differently. I like the private/public exposure here. Also, no need for any fanciful binds or anything like that ^.^
function Person(x, $button) {
// private api
function onClick(event) {
console.log(x);
}
function myMethod() {
$button.click();
}
// exports
this.x = x;
this.myMethod = myMethod;
// init
$button.click(onClick);
}
var b = $("#myBtn"),
p = new Person("foo", b);
p.x; // "foo"
p.myMethod(); // "foo"
btn.click(); // "foo"
Just assign this
to some other variable, for example _this
:
Person = function(x) {
this.x = x;
}
Person.prototype = {
myMethod: function() {
var _this = this;
$('#myBtn').click( function() {
console.log(_this.x);
});
}
}
Person = function(x) {
this.x = x;
}
Person.prototype = {
myMethod: function() {
var self = this;
$('#myBtn').click( function() {
// Access to self.x
});
}
}
A proxy would be very useful here.
Right now, you're assigning an anonymous function to the click event. By default the context will be the event's and separate from your object.
With a proxy you can assign a particular context to a (callback) function. Thus, when the event fires, you're dealing with your person object.
- Assign the event handler in a separate function like
initialize()
, and havemyMethod()
be the handler. Use a
JQuery.proxy()
to assign the object`s context to the event handler.Person.prototype = { initialize: function() { $('#myBtn').click($.proxy(this.myMethod, this)); }, myMethod: function(event) { ... console.log(this); // Person object } }
Just to elicit the difference between my and @naomik's solution:
JQuery.proxy()
is a temporary or narrow assignment to a context.Function.prototype.bind()
is a strong context assignment. The method will be "forever" bound to the context you give it.