In praise of jQuery.extend
Aug 4th, 2008 by antranig
In the interests of aiming towards slightly more bite-sized blog postings, I thought I would share with you some possibly unsuspected gems in a favorite JQuery method I kicked over recently.
Basic extending
jQuery.extend is more commonly seen as part of plugin code - the jQuery plugin model simply works by “extension” of the jQuery object itself to include new methods. For example, here is some code from the JQuery UI dialog plugin:
$.extend($.ui.dialog.overlay, {
instances: [],
events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
function(e) { return e + '.dialog-overlay'; }).join(' '),
...
The extend call is taking the existing jQuery.ui.dialog.overlay object (initially set up to be a {}) and “mixing in” a set of properties and functions from an “immediate hash”.
Multiple arguments
So far, this would account for the powers of a 3-line function, and one which we have all probably independently written for ourselves (certainly in the historical forms of fluid.mixin and RSF.assign). However, where jQuery.extend really shines is in its extensions. Firstly, it will accept any number of arguments - which are just progressively mixed in on top of its first argument:
$.extend(target, source1, source2, .... sourcen);
will “blat” all the members from the source arguments serially to arrive on top of target.
Deep copy
However, the real money of jQuery.extend is in its “deepCopy” functionality. Supplying the boolean value of true as the first argument will not just copy properties laid directly on the “source” arguments, but recursively copy any properties it finds. Here is some code from the new Fluid core initialiseThat function:
that.options = jQuery.extend(true, {}, fluid.defaults(componentName), userOptions);
This has replaced countless quantities of “options” manipulating code from around the different components, some of it quite fiddly and manual, with a single, clear, static policy in one line. The core JQuery documentation page for jQuery.extend explains this option, but in a way which might easily be missed at a quick reading. As many of the example show, it is typically used for merging “options” structures, but it is also invaluable as a plain “deep copy” operation, for example forming the basis of Fluid’s upcoming pure model idiom. Tricks like this help keep down our core library footprint.
Note on Javascript types
In such a staggeringly weakly-typed language as Javascript, this kind of useful “overloading” is generally impossible. However Javascript is at least blessed with the ability to always distinguish a handful of primitive types (string, boolean, number) from everything else, and so enables useful “Swiss army knife” methods like jQuery.extend - luckily it detectably has no meaning to try to be extending a boolean object. One way to perform this type detection is by use of the typeof operator, JQuery itself chooses to use the following test in this situation:
if ( target.constructor == Boolean ) {
Reading through the JQuery source base is highly recommended for people with a few moments to spare, who like to know what people who know what they are doing look like ![]()