Skip to main content
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with: Gert Franz
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with: Gert Franz ( @gert_railo )

Creating A JavaScript Shim For Array Unshift() Method

By on

If you write JavaScript, chances are good that you're familiar with the push() and pop() methods of an Array. These methods add and remove items to and from the end of an array, respectively. You might, however, not be as familiar with the unshift() and shift() methods of an Array. These add and remove items to and from the beginning of an array, respectively. Unshift() is a pretty awesome function; so, when I realized yesterday that I tend to use the more complex splice() method in order to achieve unshift() functionality, I was saddened.

In a response to my tweet, Aaron Cox told me that my instinct was probably good since, according to the W3C Schools website, unshift() is not actually supported in Internet Explorer (IE). Upon some subsequent testing and Googling, however, I found the W3C site to not be so accurate. Other sites do state full browser support; and, testing in my own IE 9 and IETester apps, I failed to find any occurrences where unshift() was not supported.

That said, the functionality of the unshift() method can be easily reproduced using the splice() method. As such, I thought it would be fun to write a quick shim that would implement unshift() support in any browser that didn't support it natively:

<!DOCTYPE html>
<html>
<head>
	<title>Creating A JavaScript Shim For Array Unshift() Method</title>

	<script type="text/javascript">


		// For testing, delete the native unshift method.
		delete( Array.prototype.unshift );


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


		// Check to see if this browser supports the unshift()
		// method of the Array class.
		if (!Array.prototype.hasOwnProperty( "unshift" )){

			// We are working with a partially-disabled browser;
			// let's fill in the unshift() method.
			Array.prototype.unshift = function(){

				// The unshift() method can take N-arguments to push
				// onto the front of the array. We can use splice()
				// under the hood to carry out this funciton. Prepare
				// the splice() arguments by adding two zeros: one
				// for the zero index and one for the delete count.
				Array.prototype.splice.call( arguments, 0, 0, 0, 0 );

				// Splice the "unshifted" values into place.
				Array.prototype.splice.apply( this, arguments );

				// For debuging....
				console.log( "Unshifting...." );

				// Return new length of unshifted array.
				//
				// NOTE: This return value does not seem to be
				// consistent across browsers. Firefox returns an
				// empty array natively.
				return( this.length );

			};

		}


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


		// Create an empty array.
		var collection = [];

		// Push a few items onto the end.
		collection.push( "End1", "End2" );

		// Push a few items onto the beginning using unshift().
		collection.unshift( "Begin1", "Begin2" );

		// Log the result.
		console.log( collection );


	</script>

</head>
<body>
	<!-- Left intentionally blank. -->
</body>
</html>

In this demo, you can see that I am starting out by deleting the native unshift() method. Then, I replace it with my splice()-powered shim. Since splice() can be used to both delete and insert items, unshift() can be thought of as splicing values onto the front of an array.

When we run the above code, we get the following console output:

Unshifting....
["Begin1", "Begin2", "End1", "End2"]

As you can see, this works quite nicely. Necessary or not, this was a fun little snippet of code to write. The splice() method is incredibly powerful, which is why I tend to think of it. If you ever read JavaScript: The Good Parts by Douglas Crockford, you'll actually see a number of Array methods that can be reproduced using the splice() method.

Want to use code from this post? Check out the license.

Reader Comments

15,640 Comments

@Wilkins,

Ha ha, I had never even heard of that before. Looks like an awesome resource to fill in / make up for the gaps. The W3C Schools website has helped me a lot of the past few years; but it definitely has some buggy information and lacking examples.

Thanks for the link!

71 Comments

Javascript....

JAVASCRIPT?!?!

Get back to the good stuff Ben! You're Nadel; King of the Cold(Fusion). What's with all this JS quackery?

(Ok, ok, I realize that as an application developer, you're getting into an area that's new and exciting for you, and it only makes sense that you'd make blog posts about something that interests you, so all I'm asking is for you not to forget your roots) :)

Now...if you'll excuse me, I need to get back to figuring out why my THIS scope variables are not being set in my app.cfc. I'm on day 3...

<reserved_snooty_but_respectful_attitude>
Good DAY, sir!
</reserved_snooty_but_respectful_attitude>

(And yeah, I know that tag doesn't validate...)

1 Comments

"In a response to my tweet, Aaron Cox told me that my instinct was probably good since, according to the W3C Schools website, unshift() is not actually supported in Internet Explorer (IE). Upon some subsequent testing and Googling, however, I found the W3C site to not be so accurate"

Please go again on w3fools and note that www.w3schools.com isn't related at all with the W3C, so the "W3C Schools website" does not exist.

BTW, it seems Array.prototype.unshift is supported since IE 5.5...

15,640 Comments

@Aaron,

Ha ha, I still love ColdFusion :) I swear! I just happen to code a lot of JavaScript these days. ColdFusion is still my main girl :D

@Axel,

That ES5-shim looks pretty robust. As I scroll through the code, it's definitely much more in-depth that I would have even thought to make some of those functions. Good link!

@Check_ca,

Ah, good point. I didn't truly understand the relationship between the two sites. I assumed they were related based on naming. Thanks for pointing out the truth of the matter.

383 Comments

@Aaron & @Ben,

I am coding a lot more JavaScript these days, mainly because we control the users' browsers and what they "allow" and "don't allow"...in the way of allowing JavaScript, etc., but I have to admit, it's kind of a pain to have to code in both JavaScript AND a server-side language when you have to accomodate the users/clients. (especially when time is of the essence in development). Maybe that makes me sound lazy...

15,640 Comments

@Anna,

It's kind of annoying to have to both server-side and client-side validation; but, as I have gotten into this more, I've started to realize that you can make the server-side validation much less "user friendly" since your client-side validation will take care of being more user friendly.

Hmm, that's actually an interesting topic to write about.

3 Comments

Hi Ben!

Please, update your article to clarify the terms "W3C Schools" and the relation between W3Schools and the W3C. Not everyone will read the comment ;) And I'm encouraging to mention w3fools directly in the article too ;)

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel