javascript - Array indexOf implementation for Internet Explorer - Stack Overflow

There are plenty of solutions on how to get the indexOf implementation into the Array prototype so that

There are plenty of solutions on how to get the indexOf implementation into the Array prototype so that it works under Internet Explorer, however I've stumbled upon an issue that doesn't seem to be addressed anywhere I've looked so far.

Using the pretty well agreed upon implementation at MDC, I have the following code that's being problematic now:

// indexOf support for IE (from MDC)
if (!Array.prototype.indexOf)
{
    Array.prototype.indexOf = function(elt /*, from*/)   
    {
        var len = this.length >>> 0;

        var from = Number(arguments[1]) || 0;
        from = (from < 0) ? Math.ceil(from) : Math.floor(from);
        if (from < 0)
            from += len;

        for (; from < len; from++)
        {
            if (from in this && this[from] === elt)  
                return from;
        }
        return -1;
    };
}

var i = [1,2,3,4];

for (j in i)
{
    alert(i[j]);
}

I am expecting to receive 4 alerts, each one containing one of the elements of the array. In Firefox and Chrome, that's exactly what I see, however in IE8 I get an additional alert containing the indexOf function code.

What can be done to avoid this?

There are plenty of solutions on how to get the indexOf implementation into the Array prototype so that it works under Internet Explorer, however I've stumbled upon an issue that doesn't seem to be addressed anywhere I've looked so far.

Using the pretty well agreed upon implementation at MDC, I have the following code that's being problematic now:

// indexOf support for IE (from MDC)
if (!Array.prototype.indexOf)
{
    Array.prototype.indexOf = function(elt /*, from*/)   
    {
        var len = this.length >>> 0;

        var from = Number(arguments[1]) || 0;
        from = (from < 0) ? Math.ceil(from) : Math.floor(from);
        if (from < 0)
            from += len;

        for (; from < len; from++)
        {
            if (from in this && this[from] === elt)  
                return from;
        }
        return -1;
    };
}

var i = [1,2,3,4];

for (j in i)
{
    alert(i[j]);
}

I am expecting to receive 4 alerts, each one containing one of the elements of the array. In Firefox and Chrome, that's exactly what I see, however in IE8 I get an additional alert containing the indexOf function code.

What can be done to avoid this?

Share Improve this question edited May 19, 2010 at 19:46 Pointy 414k62 gold badges594 silver badges628 bronze badges asked May 19, 2010 at 19:24 DaemonDaemon 1011 silver badge6 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

This happens because in IE, since the method doesn't exist, then it is added to the Array.prototype, and it remains being enumerable.

For woking with Arrays (and generally any array-like object), I don't remend the use of the for...in statement.

Why ?

  • The for...in statement is meant to enumerate object properties.
  • The for...in statement crawls up the prototype chain as you noticed.
  • The order of iteration can be arbitrary, iterating over an array may not visit the elements in the numeric order.

The most simple approach, the plain for loop:

for (var j = 0; j < i.length; j++) {
    alert(i[j]);
}

See also:

  • Iteration VS Enumeration

That's because you edit Array.prototype and thus any array created inherits the custom-made VISIBLE method indexOf that the "in" mand can see.

for..in construct in JavaScript doesn't act like for example PHP's foreach - it doesn't just iterate all the items in the array but also iterates all the methods and properties the array OBJECT might have (arrays in JavaScript are actually "disguised" objects). Native methods are invisible to the for..in construct but all the custom additions are not.

In your example any array would look like this:

Array:
- [0] value
- [1] value
- [2] value
- ..
- [N] value
- [IndexOf] value

To avoid the non-wanted inherited methods and properties you can use the method hasOwnProperty():

for (j in j){
    if(i.hasOwnProperty(j){
        alert(i[j])
    }
}

hasOwnProperty checks if the key is not inherited and belongs to the actual object. This way only the needed values pass through.

Can you try adding:

for (j in i) {
    if (i.hasOwnProperty(j)) { 
        alert(j); 
    }
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742345707a4426499.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信