36

When doing this:

var a = new Array("a", "b");
a.map(function() { });

in IE8 I get:

"Object doesn't support this property or method"

Is this method not supported in IE8, or do I have some other problem? I've had a Google, but get lots of Google Maps javascript issues/questions...

Edit: OK so IE8 and below DO NOT support the .map() function. Copy-paste the code from MDN here which will add the .map() function to the Array prototype exactly per the specs if not natively supported (and it seems to work perfectly).

Andrea
  • 1,057
  • 1
  • 20
  • 49
Richard H
  • 38,037
  • 37
  • 111
  • 138

5 Answers5

45

The solution is jQuery.map

Instead of this: a.map(function( ) { });

You have to do

jQuery.map(a, function( ) { //what ever you want todo .. }

  • Perfect, can't believe I missed this. You're the man, thank you! This also should be the *accepted answer*. The one above is useless. – Mark Pieszak - Trilon.io Jan 16 '14 at 20:35
  • 6
    It's useful but shouldn't be the accepted answer as others are saying. No one said the OP was using jQuery and jQuery is not the answer to everything. – Robin van Baalen Feb 11 '14 at 11:28
  • 2
    apologies to the author, but i am going to downvote this because "jQuery magically fixes everything" has become a mantra I see a lot and I'm rather sick of people relying on it for everything.. learn JavaScript, not jQuery! [Justin](http://stackoverflow.com/a/7350935/141881) has provided the MDN link in his answer and the polyfill on there works perfectly well without depending on a weighty third-party library. – pospi Apr 17 '14 at 04:06
40

IE8 doesn't support map(). When in doubt, check MDN (Mozilla Developer Network):

map - MDN

Looks like IE added support for map() in version 9.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
22
(function(fn){
    if (!fn.map) fn.map=function(f){var r=[];for(var i=0;i<this.length;i++)r.push(f(this[i]));return r}
    if (!fn.filter) fn.filter=function(f){var r=[];for(var i=0;i<this.length;i++)if(f(this[i]))r.push(this[i]);return r}
})(Array.prototype);

Put anywhere before first .map or .filter call. Problem solved. jQuery.map() method doesn't work as expected.

UPDATE: I've just tested it on sparse arrays: if map or filter argument is a function which accepts and handles undefined value - it works, but the results are not obvious:

Let's define test sparse array:

var t = []
t[1] = 1; t[3] = 3; t[5] = 5;

Let's see what does IE8 say about t: "[undefined, 1, undefined, 3, undefined, 5]"

Let's try:

t.filter(function(x){return x<4})

What is it, IE8? It's: "[1, 3]". Note - no undefined values. I would personally expect that.

But try THIS:

t.map(function(x){return 2<<x})

And... "[2, 4, 2, 16, 2, 64]". That's weird! :) Try this:

t.map(function(x){return Math.pow(2,x)})

And?... "[NaN, 2, NaN, 8, NaN, 32]" - I would rather expect this result for the previous test. It's at least logical - Math.pow() is supposed to return a number type, NaN, regardless of it's meaning IS a special number type reserved for invalid operations. So the result is more or less correct. It would be fully correct as map result if t remained a sparse array.

So without further ado - ultimately correct version of map and filter methods:

(function(fn){
    if (!fn.map) fn.map=function(f){var r=[];for(var i=0;i<this.length;i++)if(this[i]!==undefined)r[i]=f(this[i]);return r}
    if (!fn.filter) fn.filter=function(f){var r=[];for(var i=0;i<this.length;i++)if(this[i]!==undefined&&f(this[i]))r[i]=this[i];return r}
})(Array.prototype);

And the test:

var t = []; t[1] = 1; t[3] = 3; t[5] = 5;
var t1 = t.map(function(x){return 2<<x});
var t2 = t.filter(function(x){return x<10});
console.debug(t);
console.debug(t1);
console.debug(t2);

Expected results:

[object Array] [undefined, 1, undefined, 3, undefined, 5]

[object Array][undefined, 4, undefined, 16, undefined, 64]

[object Array][undefined, 1, undefined, 3, undefined, 5]

Community
  • 1
  • 1
Harry
  • 4,524
  • 4
  • 42
  • 81
7

MDN says that IE 9 supports it. No mention of IE 8.

enter image description here

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
0

On MSDN it is said in Requirements for map: Not supported in the following document modes: Quirks, Internet Explorer 6 standards, Internet Explorer 7 standards, Internet Explorer 8 standards.

Map is just a implementation of "Visitor" pattern for array. So easy substitute for it could be:

function visitArray(arr, visitor) {
    var result = [];

    for (var i = 0; i < arr.length; i ++) {
        result[i] = visitor(arr[i]);
    }

    return result;
}

The function also takes array and function which to invoke on each array element. It returns a new array with result of visitor invokation for each original array element