2012-07-16 6 views
6

Sappiamo tutti che for-in-loops su array sono absolutely evil. Tuttavia, vengono spesso utilizzati e gli errori causati sono complicati da rintracciare, soprattutto quando si verifica browser dipendente, ad esempio, a causa di indexOf -shims o simili.Questo snippet di rilevamento del ciclo for-in genera falsi positivi indesiderati?

Così, ho codificato questo semplice frammento di codice che aggiunge un getter enumerabile per un "error" proprietà su Array.prototype (non per l'uso in codice di produzione):

Object.defineProperty(Array.prototype, "error", { 
    enumerable: true, 
    get: function() { 
     if (this === Array.prototype) // that looks OK 
      return undefined; 
     if (window.confirm("Somebody who coded the site you're viewing runs through an Array with a for-in-loop.\nShame on him!\n\nDo you want to raise an Error to trace the origin?")) 
      throw new SyntaxError("Array traverse with for-in-loop, touching Array.prototype's 'error' property :-)"); 
    } 
}); 

è possibile aggiungerlo come uno script Greasemonkey per tutti i domini e vedrai gli avvisi su quasi tutti i siti :-) Molti di questi sono causati dalle chiamate allo jQuery.extend con argomenti discutibili, btw.

La mia domanda è: Ci sono situazioni che legittimano tali cicli "errati" o qualcos'altro che causa avvisi falsi positivi?

Mi chiedo come questo influirebbe sull'utilità del mio codice.

+0

Ho modificato la tua domanda per renderla meno soggettiva. Spero non ti dispiaccia. – hugomg

+0

Grazie, mi piace quella versione - non avevo idea di cosa usare come titolo :-) – Bergi

+0

Non capisco, come estendi questo a 'Array.prototype'? Dovresti usare '__lookupGetter__' o qualcosa del genere. Ora causerà semplicemente un errore perché la funzione di estensione lo otterrà e l'errore verrà generato e interromperà la copia. http://jsfiddle.net/MvgJC/ – Esailija

risposta

0

Sì. La legittimità spesso può essere soggettiva, ma ...

Per fare un esempio, forse ho un array sparso, dove ho solo valori impostati gli indici con i dati:

var a = []; 
a[123123] = "foo"; 
a[1233123] = "bar"; 

Se volessi iterare gli elementi che ho definito in questo array, quindi userei il costrutto for...in. Anche se ho codificato che difensiva, lo script sarebbe ancora innescare (un falso positivo) ...

for (var prop in a) { 
    if (a.hasOwnProperty(prop)) { 
    // this is a legitimate array element 
    } 
} 

Vedi anche Why is using "for...in" with array iteration a bad idea? per ulteriori informazioni e pareri.

+2

No, il ciclo codificato in modo difensivo (che va bene) non accederà mai a 'a [prop]' dove 'prop 'is' "error" ', quindi non sta sollevando l'eccezione. – Bergi

Problemi correlati