JavaScript: corretta iterazione di liste
In programmazione capita spessissimo di dover iterare una lista di elementi.
In JavaScript, questo è abbastanza semplice per degli Array
(che in JavaScript hanno solo indici numerici) – basta usare un loop for
‘classico’:
abc = ['a', 'b', 'c']
for (var i = 0; i < abc.length; i++) {
console.log(abc[i]);
}
A questo esempio si potrebbe fare solo una piccola obiezione: la misura della lista abc
è ricalcolata a ciascuna iterazione.
In molti casi, questo non fa differenza, ma se la lista è grande può diventare una rallentamento apprezzabile.
È una buona abitudine, quindi, evitare questo inconveniente – cosa peraltro molto semplice da fare.
Basta infatti memorizzare la lunghezza della lista prima di cominciare il loop, così:
abc = ['a', 'b', 'c']
var l = abc.length;
for (var i = 0; i < l; i++) {
console.log(abc[i]);
}
Un metodo ancora un po’ più ‘pulito’ sarebbe di utilizzare il metodo nativo forEach()
degli Array
in JavaScript:
abc = ['a', 'b', 'c']
abc.forEach(function(valore, indice, array) {
console.log(valore);
});
Lo svantaggio di questo metodo è che si tratta di una versione relativamente giovane di JavaScript (ECMAScript 5), e quindi non supportata da alcuni browser (come IE < 9).
Bisognerà compensare questa mancanza – vedi https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill.
E fin qui tutto bene. Ma… se volessi iterare una lista associativa? Nota: JavaScript non esistono array associativi, ma si possono usare oggetti normali in modo simile.
Potrebbe sembrare evidente – basta usare un loop for...in
, no?
var o = {
'uno': 'I',
'due': 'II',
'tre': 'III',
'quattro': 'IV',
'cinque': 'V'
};
for (k in o) {
console.log(k, " = ", o[k]);
}
E invece commettereste un grave errore. Il loop for...in
, infatti, non itera soltanto le proprietà di un particolare oggetto, ma tutte le sue proprietà enumerabili – quindi anche quelle ereditate dal prototype
.
Dobbiamo quindi assicurarci che le proprietà passate dal loop non provengano dal prototype
. A questo scopo usiamo il metodo hasOwnProperty
:
var o = {
'uno': 'I',
'due': 'II',
'tre': 'III',
'quattro': 'IV',
'cinque': 'V'
};
for (k in o) {
if (o.hasOwnProperty(k)) {
console.log(k, " = ", o[k]);
}
}