Using jQuery $.extend() to make even more powerful cached objects
It’s not unusual to cache reusable components in your pages onto variables so that you don’t have to reselect / reevaluate them every single time you have to do something with them.
Let’s say I had a DIV element that I can append paragraphs onto. (Every) Javascript developer worth his/her salt performs some bit of namespacing to the effect of:
<div id="foo"><!-- BLAH --></div> |
var app = { foo : $('#foo') }; |
This way, whenever I’d want to reference that DIV again, I’ll just have to call it via app.foo. I’m actively refraining from polluting the global namespace with a slew of variables for all the elements I want cached, and I have a ready jQuery element that doesn’t need re-selection every time I want to use it.
Adding in functionality
Now, say that I want to add in the functionality to actually add in the paragraphs into my DIV. I can achieve that by doing something like:
var addParagraph = function (text) { var myParagraph = $('<p></p>').text(text); app.foo.append(myParagraph); }; |
… which is perfectly valid since app.foo is, in itself, a valid jQuery object. Improving on that a bit, I’d personally stick that function into the namespace I created prior, so that I don’t add unnecessary global objects.
var app = { foo : $('#foo'), addParagraph : function (text) { var myParagraph = $('<p></p>').text(text); app.foo.append(myParagraph); } }; |
Making it even better
That’s good. But if you’re a stickler for code (as I am), you’ll probably be itching to structure the code so that app.foo owns the addParagraph function. It makes better sense to have a function that acts on an object alone to be within scope of said object. I’ve got you.
One way to go about it is something like :
app.foo.addParagraph = function (text) { var myParagraph = $('<p></p>').text(text); this.append(myParagraph); }; |
… and that on its own isn’t exactly bad, as you’re getting exactly what you want done. However, the way I’d recommend it most of the time is by using jQuery’s $.extend() function.
$.extend(app.foo, { addParagraph : function (text) { var myParagraph = $('<p></p>').text(text); this.append(myParagraph); } }); |
$.extend() isn’t something that a lot of jQuery programmers bother with (at least, I think so), but it accomplishes more or less exactly the same thing. So why, then, should I use the $.extend()?
-
It’s cleaner and easier to add in multiple functionalities at once.
If I wanted to add in more stuff, like add, edit and remove paragraph functionalities into my object, my code would most probably end up a mess. Not that it’s not possible, but it’s a bit of a maintainance nightmare to have to code something like
app.foo.add = function () {}; app.foo.edit = function () {}; app.foo.remove = function () {}; // ... some more functions
I’d rather see something like
$.extend(app.foo, { add : function () {}, edit : function () {}, remove : function () {} });
… and since we’re technically working with a plain JSON object as
$.extend()‘s second parameter, it’s perfectly valid to go this path :var paragraphFunctions = { add : function () {}, edit : function () {}, remove : function () {} }; $.extend(app.foo, paragraphFunctions);
Wouldn’t you agree that that’s much easier to look at and take care of?
-
It’s easier to work with multiple components that share the same functionality.
Not only is it easier to slap on multiple functionalities on one object, but it’s also easier to slap on the same functionalities onto multiple objects.
If I had two of those
DIVs, then traditionally I’d have to do something like this:var app = { foo : $('#foo'), bar : $('#bar') }; app.foo.add = function () {}; app.foo.edit = function () {}; app.foo.remove = function () {}; app.bar.add = function () {}; app.bar.edit = function () {}; app.bar.remove = function () {}; // yeap, I know that that's kind of a stretch
A more convenient method would be to cache a JSON object with the common functionalities, and use
$.extendto slap those onto the relevant components.var paragraphFunctions = { add : function () {}, edit : function () {}, remove : function () {} }; $.extend(app.foo, paragraphFunctions); $.extend(app.bar, paragraphFunctions);
Of course, you could also utilize Javascript prototyping at a lower level to achieve the same thing, but this is a somewhat quicker (and less complex) way of doing that.
You can check out a very rudimentary example of making it all work over on jsFiddle.
that’s is nice idea for managing function , i think i will use like that when i’m create jquery plugin..it’s look better..:)