I’ve been doing some work recently on some personal projects and I decided to use JQuery. As a long time Prototype user I found the biggest adjustment – so far – was trying to understand what was the best way to port the object-orientated Class.create() Prototype code to JQuery.
I know the idea of Class.create() doesn’t live outside of Prototype and I know there are some alternatives but for me the replacement of Class.create() with regular JavaScript .prototype syntax is fine for now at least.
The main issue I ran into is that when calling an event hander for a particular event (like a click) in JQuery using the bind() method, there is no obvious way to bind the event handler function context to the current object. Or at least that’s what I thought.
Eventually I ended up putting the question to the SO community and I finally found the answer I was looking for – use the $.proxy JQuery helper. What a revelation! I guess the lesson is not to assume a bind() in one library will be the same as a bind() in another.
So below I have an example of how to rewrite an example OO object using Prototype first and then using JQuery. The two are equivalent as far as I can tell.
First the Prototype way:
document.observe("dom:loaded", function() {
// create document
APP.pageHelper = new APP.PageHelper();
});
// namespace our code
window.APP = {};
// my class
APP.PageHelper = Class.create({
// automatically called
initialize: function(name, sound) {
this.myValue = "Foo";
// attach event handlers, binding to 'this' object
$("myButton").observe("click", this.displayMessage.bind(this))
},
displayMessage: function() {
console.log("My value: " + this.myValue); // 'this' is the object not the clicked button!
}
});
And now the JQuery way:
/* on start */
$(function() {
// create document
APP.pageHelper = new APP.PageHelper();
// need to call init manually with jQuery
APP.pageHelper.initialize();
});
// namespace our code
window.APP = {};
// my class (no Class.create in JQuery so code in native JS)
APP.PageHelper = function() {};
// add functions to the prototype
APP.PageHelper.prototype = {
// automatically called
initialize: function(name, sound) {
this.myValue = "Foo";
// attach event handlers, binding to 'this' object
$("#myButton").click($.proxy(this.displayMessage, this));
},
displayMessage: function() {
console.log("My value: " + this.myValue); // 'this' is the object not the clicked button!
}
};
The main difference is the use of the $.proxy to bind to this (more info here) and the rewrite to avoid Class.create() and instead use regular JS to code the object up.
I know there are probably other ways to accomplish this, but this exploration helped me and I hope it will help others.