Array.indexOf in Internet Explorer

According to this document at Mozilla Developer Center, Javascript 1.5 has been implemented in a browser since at least the first releases of Mozilla as open source browser, which means, in other words, since around 1998. Let’s assume it was 2002 which is marked as the release of the 1.0 version.

And I was doing some interface programming lately and I needed to check if an element was in an array. Went to Gecko’s documentation (that’s the one I normally use, since it’s less overbloated with crappy ads) and checked that Array objects had an indexOf function. Cool! I used that function on my code. Then once I finished with all the development, went to The Horror (i.e. Internet Explorer) and tested it.

Surprise! It was broken! What had I done? (You know the debugger for Internet Explorer is not specially helpful)

I suspected of the indexOf function, and recalled vague memories about doing a custom search function in the past for looking into arrays and not having to write a for(i=0; i<ar.length;i++) thing each time…

Mmmm… did a alert(‘Array.indexO’) in ie and what did I get?: undefined

So they have been spent five years for releasing ie7 and still they didn’t implement Array.indexOf!

No worries, though. Javascript is flexible! Look, IE, I don’t care if you choke on the mere seeing of indexOf, you’re going to run it whether you like it or not!

	if(!Array.indexOf){
	    Array.prototype.indexOf = function(obj){
	        for(var i=0; i<this.length; i++){
	            if(this[i]==obj){
	                return i;
	            }
	        }
	        return -1;
	    }
	}

and voila! my script wasn’t broken anymore!

98 thoughts on “Array.indexOf in Internet Explorer

  1. Funny! I was wondering if there could be a better way of doing it but I was in a rush… I haven’t played yet with mootools, since I started with jquery and didn’t want to go back and rewrite that project with mootools :)

    But I have something in mind and will probably have a look at moo for that project just before starting to code in jquery like crazy!

  2. whoa that’s crazy.. how could they have missed that?? hmm maybe it’s missing to incentivize you to use VBScript instead! ;)

  3. yay no! no vbscript!

    Which reminds me something that happened to me past year: i wanted to look for some information about rugsacks on an sports retailer site and began to click everywhere in the menu, with no luck. Nothing was happening, and I couldn’t see any Javascript error in the debug console. I thought it might be some IE only stuff going on there, but before abandoning completely, I took a look at the source and guess what!

    All the navigation was built with VBScript! I couldn’t believe it, and the worst of all is that the page was quite recently built. Absolutely fascinating.

  4. Nice!

    To improve it even more:

    When prototyping, the new method should extend all the functionality of the existing method, in order to use it completely transparent. In this case, the “start” parameter is missing. Obviously, no such a big deal but being perfectionists… ;)

  5. Thanks Nick, it’s a big compliment coming from you – I have been reading your blog and it’s got loads of interesting notes and thoughts.

  6. I own your internets!!!! HAHA!

    No, really. I guess it’s something more of a de-facto standard, or an ECMA Script standard. Or simply a common sense standard. Whatever! :-)

  7. Nice fix, this had me stumped for a while with some validation which was working fine in Firefox but borked in IE.

    Cheers!

  8. Thanks for this – ! I was scratching my head over why my indexOf wasn’t working also. Good to see someone is one step ahead of Bill Gates.

  9. Google rank 1 for ‘ie indexof array’, not bad ; ).

    I just hoped for a second this was working in IE, but I guess we’ll have to wait for 2012 the year when IE ends … : ).

  10. Oh, mighty Felix “thinking php” Geisendörfer here :)

    Yes we come to expect lots of things even on newer versions such as IE7 but it’s still as buggy as usual. Now I always assume it won’t work, and maybe it will surprise me later :D

  11. Wow thanx i was really stuck with this piece of javascript !! have spent several hours check IE and FF for what is wrong :) Thx again

  12. Thanks a lot for this – been banging my head against a wall trying to translate a nice working Firefox site into something other than a static lump in Internet Explorer. Eventually realised that it was hating indexOf and Googled – came straight here!

  13. Mmm. When you look at something like http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf you have to keep an eye out for that “ECMAScript Edition: none” tag! I was caught out myself by indexOf this week.

    This and others are in the proposals for ECMAScript 4 – http://wiki.ecmascript.org/doku.php?id=es3.1:targeted_additions_to_array_string_object_date&s=indexof – but don’t expect to see anything interesting before (or soon after!) October 2008.

    @yves geunes: myString.indexOf(“something”); isn’t going to achieve the same thing, unless you know that “something” contains no commas etc which could match element boundaries. It’s conceptually not the same search.

  14. @James – you’re right on the ECMAScript edition “little detail”, and on clarifying yves solution too. I was going to comment on that but I haven’t had time these past days.

    In any case… six years and there’s still no support for it in IE? :-) They followed the ‘defacto’ standard with the tabs in IE7, but they gave no love to the scripting engine it seems :-)

  15. @yves geunes
    Array.toString()

    The toString() is ok but you could also use the join() method like this:
    arrayObject.join().indexOf(“look for”)

    Just one warning, it is best to use this only for “single caracter” array elements like in:
    var arrayObject = new Array(“a”,”b”,”c”);

  16. Found your site through Google search… Was playing with the awesome PersistJS library (http://pablotron.org/?cid=1557) and it wigged out when the ‘remove’ function tried indexOf on an Array. I guess I’m supposed to be using Prototype or something to smooth the IE glitches… :-P

  17. Holy cannoli, Soledad, you saved my butt. My navigation scripts worked great on FF, and my heart sank to see them dead in the water on IE. After a fruitless search for decent IE debug tools, I finally located the offending line…which included indexOf. Googled “javascript indexOf IE”, your site came up, and I pasted in that lovely little code snippet and I’m back in business.

    Blessings on your family. Dalegeist.com will, thanks to you, be up and running in the twinkle of an eye.

    Dale

  18. Thanks a lot to publish this. It’s working great in IE and as well as in Mozilla. :)

  19. hi
    its realy good workin well with little modification

    if(Array.indexOf = ‘undefined’ || !Array.indexOf)
    {
    Array.prototype.indexOf = function(obj)
    {
    for(var i=0; i<this.length; i++)
    {
    if(this[i]==obj)
    {
    return i;
    }
    }
    return -1;
    }
    }

  20. Array.indexOf(value)

    Simple jQuery solution:
    jQuery.inArray(value, Array)

  21. extending the Array.prototype may work if you are only using Array.indexOf()
    but it breaks the Array object.

    the following will give unexpected results on IE if the Array.prototype is extended.
    for(var i in data) will output the Array.indexOf function as well.
    log: function (data) {
    for (var i in data){
    console.log(data[i].string);
    }
    }
    },
    if the Array is extended, then a typeof check is required before performing any operation with arrays.

  22. Wasted one whole day, thinking I am missing something in the code, but line by line debugging uncovered this issue,

    Thx

  23. Yeah it’s something odd isn’t it? You can’t believe it’s a failure in the browser’s engine and tend to blame your code :)

  24. Thank you.

    What’s weird is that my (raw, un-prototype-fixed) indexOf usage worked for a while in IE8. Then it stopped. Huh? Your code fixed it of course.

    But apparently I added document.getElementById mixed in with otherwise pure jQuery, and once that happened started IE8 barfing on indexOf.

    Freaky. Whatever. Moving on..

    Thanks again.

  25. Note that the native indexOf() method is MUCH MUCH faster than looping through all the elements in an array via JavaScript

    Shameful that IE doesn’t support this basic method…

  26. Wait! You all are missing something! The Array indexOf() method is not part of the ECMAScript Edition 3 standard. It is specific to Firefox. Just because Firefox provides it, doesn’t mean that it’s standard. In this respect, IE follows the standard. By using indexOf(), you are actually writing non-standard code. That is the problem.

    The solution is not to use indexOf(), then your code will work anywhere, and is standard-compliant.

    Besides, the moment you add to the prototype in this manner, you break the standard “for(… in …)” statement, for all of the code in your page. We just moved to a new portal framework, and the vendor’s code just broke over 600 of our for-statements, because they quietly added these methods to the prototype. What a pain!

  27. Yes, mr. NotStandard, that has been commented prior to your comment. Anyway, as you might already know, there are many types of standards, and I think we could say that a feature that is implemented in EVERY BROWSER except IE can be considered a de facto standard.

    I never said it was an standard, anyway :P

  28. sorry, not getting it, where does this script go? do I replace “Array” here with the name of my array? help me out, thanks!

    if(!Array.indexOf){
    Array.prototype.indexOf = function(obj){
    for(var i=0; i<this.length; i++){
    if(this[i]==obj){
    return i;
    }
    }
    return -1;
    }
    }

  29. I solved this by checking to see if the array has any content before running indexOf(). I’m thinking maybe IE doesn’t like running it on empty arrays? This works for me:

    if(array.length)
    index = array.indexOf(‘item’);

  30. This code seems to interfere with google maps in ie (at least using drupal gmap.module), and crashed the interpreter in firefox. I didn’t have time to track down the cause or if it was related to something else in my script, but I ended up using this method.

    function indexOf2(needle, haystack){
    if(!needle) return -1;
    if(!haystack)return -1;
    for(var i=0; i<haystack.length; i++){
    if(haystack[i]==needle){
    return i;
    }
    }
    return -1;
    }

  31. Unfortunately this doesn’t work on IE8. Any suggestion on how to get around this problem on IE8? Thanks in advance.

  32. The code I am using is this and I tried to place your code before this if or inside another tag before this, with no success: indexOf doesn’t seem to work in this case.

    if ((fileName.indexOf(“#”) != -1) ||
    (fileName.indexOf(“:”) != -1) ||
    (fileName.indexOf(“*”) != -1) ||
    (fileName.indexOf(“?”) != -1) ||
    (fileName.indexOf(“\”") != -1) ||
    (fileName.indexOf(“”) != -1) ||
    (fileName.indexOf(“|”) != -1) ||
    (fileName.indexOf(“&”) != -1) ||
    (fileName.indexOf(“[") != -1) ||
    (fileName.indexOf("]“) != -1))
    {
    alert(“”);
    document.design.screenshot.focus();
    return false;
    }

  33. Giulio, this fix is for the indexOf method of ARRAYS. You are using the indexOf method of STRINGS. It is something different.

    As to why indexOf doesn’t work in Strings with IE8, I have no idea O:-)

  34. I chuckled while reading this article. Spent 6 hours today trying to trouble shoot a ridiculous error message “Object doesn’t support this method … “. No clue what it was because the debugger was reporting different line numbers each time with the error (oh the reliability). Found this, added it to the 1 page, and hot dang, it worked. Thanks!

  35. I often still debug with alerts and discovered “” upon return from an array.indexOf function. I knew immediately my list of fixes for IE is going to get a little longer once again. Google put you right at the top searching “IE problem array.indexOf”. I guess this was a popular problem in the last 3 years.
    Your fix helped me too and I will list you in my acknowledgements. Thank you very much. What a different internet would it not be if it wasn’t for IE!?

  36. Hello, I just have a couple of comments:

    The `Array.prototype.indexOf` method is now part of the ECMAScript 5th Edition Standard (published on Dec 2009), and finally, it has been correctly implemented on IE9 (which still in its Preview stage).

    About your implementation, there are some flaws that I would like to address.

    Checking:

    if(!Array.indexOf){
    //..
    }

    And later assigning the `Array.prototype.indexOf` property is not right, they two are different methods!

    `Array.indexOf` is part of the “Array Generics” methods, introduced on the Mozilla Implementations only! (Rhino and SpiderMonkey, in JavaScript(TM) 1.7), and it is not part of the ECMAScript standard.

    `Array.indexOf` does *not* exist on other ECMA-compliant implementations, for example in Safari, Chrome, WebKit and even in IE9, while they do implement the standard native `Array.prototype.indexOf` method.

    This means that in those implementations the native method will be replaced with your code!, and that’s pretty bad, native methods are extremely fast and should be respected (check for `Array.prototype.indexOf`!).

    In the ECMAScript 5th Edition Standard the method is completely described ( http://j.mp/cqP6r7 ), it needs to handle a second argument, a “fromIndex” to start the search looking forward from it (which can also be negative, in that case it will be taken as the offset from the end of the array).

    Also, the method should compare the elements of the array using the Strict Equality operator, `===`. Comparing with the equals operator `==` will give you different results, for example:

    ['0'].indexOf(0); // Should return `-1`

    But your implementation will return `0`, because the `===` operator does not make any type conversion (`’0′ == 0` produces true but `’0′ === 0` evaluates to false).

    Aside of that, the method is described in the specification as “generic”, that means that it can be used on “array-like” objects, (an object that has a `length` property, and its value should be within the range of a 32-bit unsigned integer (from 0 to 2^32-1) and that contains numeric properties), e.g.:

    var arrayLike = {0:’foo’, length:1};
    Array.prototype.indexOf.call(arrayLike, ‘foo’); // 0

    Your method is capable to handle the above example, but imagine what would happen if `length` were an arbitrary value like `Infinity` for example…

    The algorithm described in the specification also checks the value of the `length` property ensuring that it is a Uint32…

    There are even more aspects that a standards compliant implementation should check, but this comment is getting quite long :-)

    A complete standards compliant method can be found on the Mozilla Developer Center: http://j.mp/aQtCpG

    Thanks!

  37. I FOUND THIS A VERY GOOD SOLUTION!

    Marius

    20080625 Array.indexOf(value)

    Simple jQuery solution:
    jQuery.inArray(value, Array)

  38. pity that IE has many javascript functions that mozilla doesn’t but falls short on something as simple as indexOf.

  39. hi @all. i am using the jquery multi day-plugin (from overset.com) and have a problem with inArray. here is my code

    var arr = ['10.11.2010','11.11.2010'];

    if ($.inArray(
    [day.getDate(), (day.getMonth() + 1), day.getFullYear()].join(‘.’),
    arr) != -1) ..

    that works but the variable arr doesn’t consists of two values. so i decided to get the values from an get-function:

    function getreservedDates()
    {
    var res = “”;
    id=”";

    res = $.ajax({
    type: “GET”,
    url: “config/get-reserved-dates-from-books.php”, //e.g. return “’10.11.2010′, ’11.11.2010′”;
    async: false
    }).responseText;

    return res;
    }

    after that i modified my code:

    if ($.inArray(
    [day.getDate(), (day.getMonth() + 1), day.getFullYear()].join(‘.’),
    getreservedDates()) != -1) ..

    the return-values will not shown but in the inArray method!!!

    why???

  40. I honestly have no idea. I’m approving the comment just in case some kind visitor can help you, but maybe you should try your luck in a jQuery specific site, or somewhere where they know what that multi day plugin is, because I don’t :D

    Good luck!

  41. Of note, this fix lead to an unintended consequence that took me a while to debug.

    I was doing something like

    for (var i in array) …

    And this was failing. Eventually I figured out that, since we’ve added an indexOf property, that was being passed along as one of the values for i, i.e.

    array[i] would be equivalent to array[indexOf], which of course is pretty nonsensical…

    The solution was to switch the loop to a normal for loop, e.g. for (var i=0; i<array.length; i++)

  42. Yep, someone mentioned that on the comments :-)

    It’s a fix but it has some other consequences…

Comments are closed.