Domanda

Ci sono un sacco di soluzioni su come ottenere l'attuazione indexOf nel prototipo Array in modo che funzioni in Internet Explorer, tuttavia ho inciampato su un problema che non sembra essere indirizzata da nessuna parte ho guardato finora .

Uso della abbastanza bene concordato a MDC , ho il seguente codice che viene problematica ora:

// 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]);
}

Mi aspetto di ricevere avvisi 4, ognuno contenente uno degli elementi dell'array. In Firefox e Chrome, questo è esattamente quello che vedo, tuttavia in IE8 ottengo un avviso aggiuntivo contenente il codice della funzione indexOf.

Cosa si può fare per evitare questo?

È stato utile?

Soluzione

Questo perché modificare Array.prototype e quindi eventuali eredita matrice creato il metodo VISIBILE indexOf su misura che il "in" comando può vedere.

for..in costrutto in JavaScript non agisce come ad esempio foreach del PHP - lo fa non solo iterazione tutti gli elementi dell'array, ma anche itera tutti i metodi e le proprietà dell'oggetto Array potrebbe avere (array in JavaScript sono in realtà "mascherati "oggetti). metodi nativi sono invisibili al costrutto for..in ma tutte le aggiunte personalizzati non sono.

Nel tuo esempio qualsiasi array sarebbe simile a questa:

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

Per evitare i metodi e le proprietà non-wanted ereditati è possibile utilizzare il metodo hasOwnProperty():

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

controlli hasOwnProperty se la chiave non è ereditaria e appartiene all'oggetto reale. In questo modo solo i valori necessari passi attraverso.

Altri suggerimenti

Ciò accade perché in IE, dato che il metodo non esiste, allora viene aggiunto al Array.prototype, e rimane essendo enumerable.

Per woking con Array (e in generale qualsiasi array come oggetto), I sconsiglia l'uso della dichiarazione for...in.

Perché?

  • La dichiarazione for...in ha lo scopo di enumerate le proprietà degli oggetti.
  • La dichiarazione for...in striscia la catena di prototipi come avete notato.
  • L'ordine di iterazione può essere arbitraria, iterazione su una matrice non possono visitare gli elementi in ordine numerico.

L'approccio più semplice, il ciclo for pianura:

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

Vedi anche:

Si può provare ad aggiungere:

for (j in i) {
    if (i.hasOwnProperty(j)) { 
        alert(j); 
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top