Andres SK
Andres SK

Reputation: 10974

Javascript: Having trouble with .map() on IE

This code runs great on Chrome, FFX, etc. It takes the content of a textarea and separates all lines in different array items (new lines are represented by empty array items). When testing it on IE, it throws an error. Code:

This is tregex's value and the call:

var tregex = /\n|([^\r\n.!?]+([.!?]+|$))/gim;

var source = $('#text').val().match(tregex).map($.trim);

The code throws this error message because of .map() (IE only)

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) Timestamp: Fri, 13 Jul 2012 21:52:48 UTC

Message: Object doesn't support this property or method Line: 128 Char: 6 Code: 0 URI: http://mydomain.com/src/common.js

Why? Any way I can support it on IE7+? (this was tested on IE8).

Upvotes: 1

Views: 5109

Answers (4)

Esailija
Esailija

Reputation: 140230

You can add the support just by including the shim for it:

// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.com/#x15.4.4.19
if (!Array.prototype.map) {
  Array.prototype.map = function(callback, thisArg) {

    var T, A, k;

    if (this == null) {
      throw new TypeError(" this is null or not defined");
    }

    // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length >>> 0;

    // 4. If IsCallable(callback) is false, throw a TypeError exception.
    // See: http://es5.github.com/#x9.11
    if ({}.toString.call(callback) != "[object Function]") {
      throw new TypeError(callback + " is not a function");
    }

    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
    if (thisArg) {
      T = thisArg;
    }

    // 6. Let A be a new array created as if by the expression new Array(len) where Array is
    // the standard built-in constructor with that name and len is the value of len.
    A = new Array(len);

    // 7. Let k be 0
    k = 0;

    // 8. Repeat, while k < len
    while(k < len) {

      var kValue, mappedValue;

      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      if (k in O) {

        // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
        kValue = O[ k ];

        // ii. Let mappedValue be the result of calling the Call internal method of callback
        // with T as the this value and argument list containing kValue, k, and O.
        mappedValue = callback.call(T, kValue, k, O);

        // iii. Call the DefineOwnProperty internal method of A with arguments
        // Pk, Property Descriptor {Value: mappedValue, Writable: true, Enumerable: true, Configurable: true},
        // and false.

        // In browsers that support Object.defineProperty, use the following:
        // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });

        // For best browser support, use the following:
        A[ k ] = mappedValue;
      }
      // d. Increase k by 1.
      k++;
    }

    // 9. return A
    return A;
  };      
}

You can also include the es5shim which adds .map and all the other missing array methods in IE7-8 plus other goods like Function#bind

Upvotes: 0

Brian Nickel
Brian Nickel

Reputation: 27550

I believe your code may be working in FF and Chrome by accident. Did you mean to use jQuery.map? You are using Array.map which isn't supported in IE prior to 9.

Consider the following as a replacement.

var source = $.map($('#text').val().match(tregex), $.trim);

This uses jQuery's map implementation to loop through and do the trim.

Upvotes: 1

machineghost
machineghost

Reputation: 35790

IE is a terrible browser, and as such doesn't have a built-in map function (at least not in IE7-8). Since you're trying to call map on the results of a Regular Expression match (as opposed to calling it on a jQuery results object), the only map you can use is the built-in one (that IE doesn't have).

There are many libraries that simulate map for you however, including jQuery, Underscore, and Mochikit.

Here's an example of how you could use jQuery's to do what you're trying to do:

$.map($('#text').val().match(tregex), $.trim);

Upvotes: 2

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324650

I'm fairly sure Array.map() was only added in IE9. You should loop through the array manually instead.

Upvotes: 0

Related Questions