Skip to main content
Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.

Using Self-Executing Function Arguments To Override Core jQuery Methods

By Ben Nadel on

Overriding jQuery methods (or any function for that matter) is a relatively straight forward process. All you have to do is get a reference to the old method (if you need to keep it) and then override the object key (method name) using your new function. A while back, however, I was reading Eric Hynds' blog and came across what I thought was a really elegant way to do this. He was using self-executing function arguments to create a reference to the old jQuery method that he was about to override.

When you create a self-executing function block, you have the opportunity to pass in parameters as part of the function invocation:

(function( argA, argB ){ .... })( paramA, paramB );

In this case, we are passing in "paramA" and "paramB", which will become the arguments, "argA" and "argB," respectively. This approach has a number of benefits including cutting down on scope-chain traversal and creating reference short-hands (ex. mapping "jQuery" parameter to "$" argument). What Eric was doing, that I found so interesting, was that he was using this parameter-argument approach to create references to methods that he was going to override.

To see this in action, I created a very brief demo that overrides the core jQuery method, html(). In the following code, I am going to prepend my own string data to any given HTML before I pass it off to the original, now wrapped, html() method:

<!DOCTYPE html>
<html>
<head>
	<title>Overriding Core jQuery Methods</title>
	<script type="text/javascript" src="./jquery-1.4.2.js"></script>
	<script type="text/javascript">

		// Create a self-executing function block to which we are
		// going to pass the jQuery object and a reference to the
		// original, core method, html().
		(function( $, oldHtmlMethod ){

			// Override the core html method in the jQuery object.
			$.fn.html = function(){

				// Check to see if we have an argument (that the user
				// is setting HTML content).
				//
				// NOTE: This does not take into account the fact
				// that we can now pass a function to this method -
				// this is just a lightweight demo.
				if (arguments.length){

					// Prepend our own custom HTML.
					arguments[ 0 ] = (
						"<strong>HTML: </strong>" +
						arguments[ 0 ]
					);

				}

				// Execute the original HTML method using the
				// augmented arguments collection.
				return(
					oldHtmlMethod.apply( this, arguments )
				);

			};

		})( jQuery, jQuery.fn.html );


		// -------------------------------------------------- //
		// -------------------------------------------------- //


		// When the DOM is ready, run scripts.
		$(function(){

			// Use the HTML method which, at this point, has been
			// overridden with a wrapper behavior.
			$( "body" ).html( "I was appended to BODY!" );

		});

	</script>
</head>
<body>
	<!-- Intentionally left blank. -->
</body>
</html>

When I run this code, the BODY of the page now contains the following content:

HTML: I was appended to BODY!

As you can see, "HTML:" was prepended to the HTML string that we passed into the html() method.

In the above code, when I defined the self-executing function block, I passed in two parameters: the jQuery library (jQuery) and a reference to the core html() method (jQuery.fn.html). These parameters then became arguments for the self-executing function invocation, which allowed for an almost quasi-implicit reference to the original html() method.

From a functional standpoint, there's absolutely no difference between using this approach and just creating a local variable reference to the original method:

var oldHtmlMethod = $.fn.html;

However, there's something that just feels really nice about parameter-argument mapping in this context. Perhaps I just like the fact that the reference-logic was factored out of the override-logic, creating a slightly cleaner separation of concerns.



Reader Comments

Good idiom - it's nice how everything happens in "one line". A lot of the time, people won't make that "var oldHtmlMethod = $.fn.html;" a local variable either, ie. it will stick around in global scope, which is possibly undesirable, and something this idiom removes.

@Michael,

Good point on leaving stuff in the global scope; using this parameter-argument approach will definitely help keep variables in the preferred scoping.

Nice post. We use this technique to add in extra functionality to jQuery's $.ajax() function. The overridden success argument, for example, looks into the returned JSON object to see if a property called ERROR has been given. That way, we can pass along a localized error message directly from the server without any extra fuss - and even though the ajax request was technically "successful" we prevent the success handler from being run in the case of one of these errors.

I put up a Gist to better explain :)
http://gist.github.com/577713

@Jordan,

Both links worked for me. I like what you're doing. Clearly, this is something very specific to your particular application configuration; but, that said, it looks like it helps unify the API functionality.

@Pomeh,

You could certainly do that; but you still need to create a local variable for the old method reference. Part of what I was demonstrating here was the use of parameter-argument mapping to remove the local variable. Again, no functional difference, just something I liked about it. I like that you don't have to repeat the function name, however - nice idea.

@Alex,

Ha ha, yeah "Duck Punching" is definitely a more catchy phrase.... although, Aspect Oriented Programming sounds very sophisticated.