Applying OOP with jQuery
I'm working with jQuery and trying to apply some basic Javascript OOP principles to a set of functions that control hover behavior. However, I can't figure out how to get the "this" keyword to refer 开发者_如何学Goto the instance of the object I'm creating. My sample code is:
var zoomin = new Object();
zoomin = function() {
// Constructor goes here
};
zoomin.prototype = {
hoverOn: function() {
this.hoverReset();
// More logic here using jQuery's $(this)...
},
hoverReset: function() {
// Some logic here.
}
};
// Create new instance of zoomin and apply event handler to matching classes.
var my_zoomin = new zoomin();
$(".some_class").hover(my_zoomin.hoverOn, function() { return null; });
The problematic line in the above code is the call to this.hoverReset()
inside the hoverOn()
function. Since this
now refers to element that was hovered on, it does not work as intended. I would basically like to call the function hoverReset()
for that instance of the object (my_zoomin)
.
Is there any way to do this?
Only assigning a function to a property of an object does not associated this
inside the function with the object. It is the way how you call the function.
By calling
.hover(my_zoomin.hoverOn,...)
you are only passing the function. It will not "remember" to which object it belonged. What you can do is to pass an anonymous function and call hoverOn
inside:
.hover(function(){ my_zoomin.hoverOn(); },...)
This will make the this
inside hoverOn
refer to my_zoomin
. So the call to this.hoverReset()
will work. However, inside hoverOn
, you will not have a reference to the jQuery object created by the selector.
One solution would be to pass the selected elements as parameter:
var zoomin = function() {
// Constructor goes here
};
zoomin.prototype = {
hoverOn: function($ele) {
this.hoverReset($ele);
// More logic here using jQuery's $ele...
},
hoverReset: function($ele) {
// Some logic here.
}
};
var my_zoomin = new zoomin();
$(".some_class").hover(function() {
my_zoomin.hoverOn($(this)); // pass $(this) to the method
}, function() {
return null;
});
As a next step, you could consider making a jQuery plugin.
- You can "bind" the event handler to the object (see Mootools bind code for example).
- You can pass the object as a parameter in the anonymous function and use that instead of
this
in the event handler
As for 1, you add the bind
method to function
bind: function(bind){
var self = this,
args = (arguments.length > 1) ? Array.slice(arguments, 1) : null;
return function(){
if (!args && !arguments.length) return self.call(bind);
if (args && arguments.length) return self.apply(bind, args.concat(Array.from(arguments)));
return self.apply(bind, args || arguments);
};
}
Not sure though how well it will interact with JQ stuff.
please see my answers to these questions:
where is my "this"?
why is "this" not this?
this
confusion comes up all the time.
when you pass a function in as a callback, it's invoked as a standalone function, so its "this" becomes the global object.
"bind" is a native part of ecmascript 5, and is part of the function prototype. If you go to the end of my second answer up there, you get a link to the mozilla website, which has a "compatibility" version of the bind function. Use use myfunction.bind(myobject), and it'll use the native function if it's available, or the JS function if it is not.
精彩评论