Reputation: 21381
This is an example of my code:
var bar = function() {
this.baz = function() {
this.input = $('.input');
this.input.bind("keydown keyup focus blur change", this.foo);
}
this.foo = function(event){
console.log(this);
}
}
Clicking on my input gives me the input
in the console, obviously. How can i get bar
as this
instead?
Upvotes: 3
Views: 2339
Reputation: 827256
That happens because when you bind an event, the event handler function is called with the context of the DOM element which triggered the event, the this
keyword represents the DOM element.
For getting "bar" you should store a reference to the outer closure:
var bar = function() {
var self = this;
this.baz = function() {
this.input = $('.input');
this.input.bind("keydown keyup focus blur change", this.foo);
}
this.foo = function(event){
console.log(this); // the input
console.log(self); // the bar scope
}
};
Note: If the bar function is called without the new
operator, this
will be the window object and baz
and foo
will become global variables, be carefull!
However I think your code can be simplified:
var bar = {
baz: function() {
var input = $('.input');
input.bind("keydown keyup focus blur change", this.foo);
},
foo: function(event){
console.log(this); // the input
console.log(bar); // reference to the bar object
}
};
Upvotes: 5
Reputation: 3117
This is a general problem when using instance methods as callbacks in JavaScript. I use this function to create a closure to call the method bound to the correct instance:
function bound_method(instance, method) {
return function() {
return method.apply(instance, arguments);
};
}
Then you can use this as your callback in place of this.foo:
bound_method(this, this.foo)
Unlike some of the other proposals, this allows you to put the methods on the prototype instead of creating them in the constructor. This way you only have one shared copy of the implementation instead of re-creating those functions for each new instance of bar.
var bar = function() {};
$.extend(bar, {
baz: function() {
this.input = $('.input');
this.input.bind("keydown keyup focus blur change",
bound_method(this, this.foo));
},
foo: function(event) {
console.log(this);
}
});
Upvotes: 1
Reputation: 3411
Here you go.this is an exmaple of how to get "this"
<html>
<head></head>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script>
var bar = function() {
this.baz = function() {
this.input = $('.input');
this.input.bind("keydown keyup focus blur change", this.foo);
}
this.foo = function(event){
console.log(this);
}
}
</script>
<body>
<input class="input">
<button onclick="new bar().baz()">Click</button>
</body>
</html>
This happens because the function baz is called with an instance of bar.SO bar is executing within the "new bar()" context and not the window object.
If you are using firebug (it seems so), you can track the logging as you type inside the input text control before and after clicking the click within the console tab.
Upvotes: 0
Reputation: 8413
to get bar in your foo do this:
bar = function() {
var me = this;
this.baz = function() {
this.input = $('.input');
this.input.bind("keydown keyup focus blur change", this.foo);
}
this.foo = function(event){
// me, would be your bar object.
console.log(me);
}
}
Upvotes: 1