Creating A JavaScript Shim For Array Unshift() Method

Posted December 22, 2011 at 9:26 AM by Ben Nadel

Tags: Javascript / DHTML

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.


 
 
 

 
I find that I often think of using splice() before I think of using unshift() on JavaScript arrays. This saddens me. 
 
 
 

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.




Reader Comments

Dec 22, 2011 at 9:48 AM // reply »
10 Comments

Next time go to w3fools.com. :P


Dec 22, 2011 at 9:51 AM // reply »
10,743 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!


Dec 23, 2011 at 11:06 AM // reply »
31 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...)


Dec 23, 2011 at 5:37 PM // reply »
2 Comments

I want to ask how to learn the basics of JavaScript?

Thanks!


Dec 27, 2011 at 9:10 AM // reply »
2 Comments

@Dean: There are many good introductory resources available online, for free. I've collected them here:
http://jscentral.org/links.html


Dec 27, 2011 at 9:12 AM // reply »
2 Comments

I'm a big fan of es5-shim [1] (which implements most ECMAScript 5 features on top of ECMAScript 3). It doesn't seem to add Array.prototype.unshift(), but maybe it should.

[1] https://github.com/kriskowal/es5-shim


Dec 27, 2011 at 9:22 AM // reply »
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...


Dec 28, 2011 at 6:55 AM // reply »
2 Comments

Thanks Alex!


Dec 28, 2011 at 8:43 AM // reply »
10,743 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.


Dec 28, 2011 at 10:52 AM // reply »
347 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...


Dec 28, 2011 at 11:02 AM // reply »
10,743 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.


Dec 28, 2011 at 4:13 PM // reply »
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 ;)


Dec 28, 2011 at 4:18 PM // reply »
10,743 Comments

@Thomas,

I'll try to carve out some time to make the updates.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 21, 2012 at 1:58 AM
Updated: Converting A ColdFusion Query To CSV Using QueryToCSV()
Hi Ben, why do you need to have so many double quotes when adding the field and field name to the row data? ----------------------------------------- <cfset LOCAL.RowData[ LOCAL.ColumnIndex ] = ... read »
AXL
May 21, 2012 at 1:24 AM
URL Rewriting And ColdFusion's WriteToBrowser Image Functionality (CFFileServlet)
@Mounir, Open your lower case URL Rewrite rule and add the following condition. Condition input: {REQUEST_URI} Check if input string: Does Not Match the Pattern Pattern: ^/CFFileServlet/_cf_ca ... read »
May 20, 2012 at 4:28 AM
Understanding The Complex And Circular Relationships Between Objects In JavaScript
@Will Vaughn I tried your javascript example but got this error:- foo.print is not a function ... read »
May 19, 2012 at 5:37 AM
A Graphical Explanation Of Javascript Closures In A jQuery Context
Thanks for this article, but I fear you missed an important point. If variables in the outer context change, these changes affect the inner anonymous functions as well. That means: if you change the ... read »
May 18, 2012 at 3:39 PM
Parsing CSV Data With An Input Stream And A Finite State Machine
Can you use file upload button with this? and read live? or does the file have to already be on the server saved? ... read »
May 18, 2012 at 1:06 AM
VIRGO (Aug. 23-Sept. 22): Dead On The Money!
A friend of mine and I were arguing about astrology and she told me that he believes in astrology. She hasn't provided me with any evidence that the belief makes any sense to me. She she been telling ... read »
May 17, 2012 at 11:32 PM
Using ColdFusion to Handle 404 Errors (Page Not Found) On Development Server
Very easy the configuration. I read a lot pages and I can't find the solution. I open the administrator and change this Administrator/server settings/Error Handlers/Missing Template Handler and p ... read »
May 17, 2012 at 3:13 PM
LOCAL Variables Scope Conflicts With ColdFusion Query of Queries
I never cease to be amazed that almost EVERY random CF issue I come across lands me on your site. Thank you for documenting your findings for the world. ... read »