Javascript: nascondendo i metodi del prototipo in ciclo for?

Quindi diciamo che ho aggiunto alcuni metodi di prototipo alla class Array:

Array.prototype.containsKey = function(obj) { for(var key in this) if (key == obj) return true; return false; } Array.prototype.containsValue = function(obj) { for(var key in this) if (this[key] == obj) return true; return false; } 

quindi creo un array associativo e cerco di scorrere le sue chiavi:

 var arr = new Array(); arr['One'] = 1; arr['Two'] = 2; arr['Three'] = 3; for(var key in arr) alert(key); 

questo restituisce cinque elementi:

   -Uno
   -Due
   -Tre
   -containsKey
   -containsValue

ma voglio (aspetta?) solo tre. Mi sto avvicinando a questo torto? c’è un modo per “hide” i metodi del prototipo? o dovrei fare qualcosa in modo diverso?

Puoi utilizzare il metodo hasOwnProperty di JavaScript per ottenere questo risultato nel ciclo, come questo:

 for(var key in arr) { if (arr.hasOwnProperty(key)) { ... } } 

Riferimento: questo articolo del blog YUI .

È ansible ottenere risultati desiderati dall’altra parte rendendo i metodi prototipo non enumerabili:

 Object.defineProperty(Array.prototype, "containsKey", { enumerable: false, value: function(obj) { for(var key in this) if (key == obj) return true; return false; } }); 

Questo di solito funziona meglio se si ha il controllo sulle definizioni dei metodi, e in particolare se non si ha il controllo su come il codice verrà chiamato da altre persone, che è un’ipotesi comune nello sviluppo del codice libreria.

Javascript non supporta gli array associativi nel modo in cui pensi che facciano. http://ajaxian.com/archives/javascript-associative-arrays-considered-harmful

for (var i in .. ottiene tutte le proprietà di un object (una matrice è solo un altro object) ed è per questo che stai vedendo gli altri oggetti a cui hai fatto il prototipo.

Come suggerisce l’articolo dovresti usare un object:

 var assoc = {'One' : 1, 'Two' : 2}; assoc['Three'] = 3; for(var key in assoc) alert(key+' => '+assoc[key]); 

potresti fare questo:

 for(var key in arr) { if (typeof(arr[key]) == "function") continue; alert(key); } 

Ma questa è una soluzione scadente

Per l’iterazione ad alte prestazioni su array JavaScript, utilizzare un ciclo for o while . Nicholas Zakas discute le opzioni più performanti per iterare su array nel suo Tech Talk. Velocizza il tuo JavaScript .

La tua migliore scommessa è probabilmente qualcosa del genere:

 for (var i = collection.length - 1; i >= 0; i--) { if (obj == collection[i]) return true; } 

Questo approccio sarà migliore per diversi motivi:

  • Viene assegnata solo una singola variabile locale
  • La proprietà della length della raccolta è accessibile solo una volta, durante l’inizializzazione del ciclo
  • Ogni iterazione, un locale viene confrontato con una costante ( i >= 0 ) anziché con un’altra variabile

Metodo 1 : utilizzare Object.keys (che non restituisce le proprietà del prototipo) e il ciclo

 Object.keys(arr); // ['One', 'Two', 'Three'] Object.keys(arr).forEach(key => console.log(key)) 

Metodo 2 : hasOwnProperty all’interno di un ciclo for.

  for(var key in arr) { if (arr.hasOwnProperty(key)) { ... } }