How to fix Array indexOf() in JavaScript for Internet Explorer browsers

178,230

Solution 1

Do it like this...

if (!Array.prototype.indexOf) {

}

As recommended compatibility by MDC.

In general, browser detection code is a big no-no.

Solution 2

Alternatively, you could use the jQuery 1.2 inArray function, which should work across browsers:

jQuery.inArray( value, array [, fromIndex ] )

Solution 3

The full code then would be this:

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

For a really thorough answer and code to this as well as other array functions check out Stack Overflow question Fixing JavaScript Array functions in Internet Explorer (indexOf, forEach, etc.).

Solution 4

The underscore.js library has an indexOf function you can use instead:

_.indexOf([1, 2, 3], 2)

Solution 5

You should check if it's not defined using if (!Array.prototype.indexOf).

Also, your implementation of indexOf is not correct. You must use === instead of == in your if (this[i] == obj) statement, otherwise [4,"5"].indexOf(5) would be 1 according to your implementation, which is incorrect.

I recommend you use the implementation on MDC.

Share:
178,230

Related videos on Youtube

jonen
Author by

jonen

Updated on January 28, 2020

Comments

  • jonen
    jonen over 4 years

    If you have worked with JavaScript at any length you are aware that Internet Explorer does not implement the ECMAScript function for Array.prototype.indexOf() [including Internet Explorer 8]. It is not a huge problem, because you can extend the functionality on your page with the following code.

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

    When should I implement this?

    Should I wrap it on all my pages with the following check, which checks if the prototype function exists and if not, go ahead and extend the Array prototype?

    if (!Array.prototype.indexOf) {
    
        // Implement function here
    
    }
    

    Or do browser check and if it is Internet Explorer then just implement it?

    //Pseudo-code
    
    if (browser == IE Style Browser) {
    
         // Implement function here
    
    }
    
    • Crescent Fresh
      Crescent Fresh over 14 years
      Actually Array.prototype.indexOf is not part of ECMA-262/ECMAScript. See ecma-international.org/publications/files/ECMA-ST/ECMA-262.p‌​df Maybe you're thinking String.prototype.indexOf...
    • Josh Stodola
      Josh Stodola over 14 years
      It's an extension, not part of the original standard. It should, however, be implemented as part of Javascript 1.6 (which IE fails to do) developer.mozilla.org/en/New_in_JavaScript_1.6
    • Crescent Fresh
      Crescent Fresh over 14 years
      @Josh: was just referring to "IE does not implement the ECMAScript function..."
    • nickf
      nickf over 13 years
      Your implementation of Array.indexOf doesn't take negative starting indices into account. See Mozilla's suggestion stop-gap implementation here: developer.mozilla.org/en/JavaScript/Reference/Global_Objects‌​/…
    • joshcomley
      joshcomley about 13 years
      I've updated the question to use "===", because I'm worried people will copy it with the "==" and that would be wrong - other than that it's fine. See Eli Grey's answer.
    • Denis V
      Denis V over 10 years
      Actually, Array.prototype.indexOf is a part of ECMAScript 5 (where the link to the standard now goes): "15.4.4.14 Array.prototype.indexOf ( searchElement [ , fromIndex ] )"
  • jonen
    jonen over 14 years
    I don't have enough rep to edit the question but feel free to remove the ECMAScript lingo and replace with the appropriate wording. Thanks Again
  • a1ashiish
    a1ashiish over 14 years
    Be careful if you use this kind of detection. Another library might implement this function before you test it, and it might not be standards compliant (prototype has done it a while ago). If I were working in a hostile environment (lots of other coders using lots of distinct libraries), I wouldn't trust any of these...
  • Josh Mc
    Josh Mc almost 12 years
    ** Although I will note that I have had problems in IE7 with this lib.
  • Brad Koch
    Brad Koch over 11 years
    This answer avoids messing with the array prototype, and it delegates to the native indexOf when available. I like it.
  • Dan
    Dan about 11 years
    The 'indexOf' is native code (right), so will the jQuery 'inArray()' be as fast, such as use native when available and poly-fill when not?
  • Dan
    Dan about 11 years
    Ok so to answer my own comment (above), I just implemented it and on Chrome it's as fast as when I was using 'indexOf()', but in IE 8 it is very, very slow... so at least we know that 'inArray()' uses native when it can.
  • gordon
    gordon over 8 years
    The "Linked" column ---> is really handy! I love the answer here: stackoverflow.com/questions/1744310/…
  • ste2425
    ste2425 over 8 years
    Just being pedantic but MDN is not just Mozilla. It is a community driven project that contains Mozilla staff but also volunteers, anyone can join and contribute.
  • rd22
    rd22 about 8 years
    Does it has to be wrapped in every js file?
  • ChrisRich
    ChrisRich about 8 years
    Seems to be the easiest way if you are able to include underscore or lodash
  • dylnmc
    dylnmc almost 7 years
    thank you for just having the full thing. I visit this page frequently whenever I need cross-platform indexOf in a new project, and your snippet is the only one with full code. :) Those few seconds really add up when one frequents this page.
  • Ferrybig
    Ferrybig almost 6 years
    Who is MDC exactly?