2015-08-17 16 views
5

Recentemente mi sono imbattuto nel problema dell'utilizzo di for..in loop su array in JavaScript.JavaScript: proprietà non numerabili: quando e perché?

In base alle risposte nella domanda this, for..in è inteso per enumerare le proprietà di un oggetto, incluse quelle ereditate.

In tal caso, perché è possibile definire proprietà come non enumerabili utilizzando Object.defineProperty? Questo non va contro l'intera intenzione di ... in? O è considerato una cattiva pratica e dovrebbe essere evitato?

Inoltre, perché dovremmo voler ripetere tutte le proprietà in questo modo in primo luogo (cioè utilizzando un ciclo for..in)? Quando potrebbe essere utile?

E perché non definire tutte le estensioni di prototipo (Array) come non enumerabili e continuare a utilizzare for..in con gli array?

risposta

6

Il problema è che esiste un solo spazio dei nomi per le proprietà dell'oggetto (ignorando la funzione Simbolo in ES2015 per ora). Ci sono alcune proprietà dell'oggetto che tu do vuoi essere enumerabile e altre no. Le proprietà che contengono dati oggetto e relazioni con altri oggetti condividono tale spazio dei nomi con i nomi dei metodi.

Il ciclo for ... in non guarda solo alle proprietà dell'oggetto direttamente coinvolto, ma anche alla catena del prototipo. Questo è probabilmente l'uso più probabile per le proprietà non enumerabili: i metodi che potresti voler mettere su un oggetto prototipo probabilmente non devono essere enumerabili.

Per me la vera ragione per non utilizzare for ... in quando si sta iterando attraverso le proprietà del nome numerico di un'istanza di Array è che non c'è alcuna garanzia che itererà attraverso gli indici in un ordine particolare. Sebbene la maggior parte dei sistemi di runtime do restituiscano le proprietà del nome numerico nell'ordine evidente, la specifica per la lingua non richiede assolutamente che sia così. Utilizzando un indice numerico esplicito in un ciclo normale for, è quindi possibile controllare esplicitamente l'ordine di iterazione.

Le persone che scrivono il codice JavaScript per l'utilizzo in contesti in cui ci sarà un altro codice in esecuzione su cui non hanno alcun controllo (si pensi ai siti pubblicitari supportati o ai siti con molti strumenti di metrica) sanno che si basano su prototipi incorporati non essere inquinato da spazzatura casuale è profondamente poco saggio. L'utilizzo di for ... in mette il tuo codice in balia del peggiore programmatore che contribuisce a quel codice di terze parti.

Le implementazioni moderne hanno Object.keys(), che restituisce i nomi di proprietà "propri" enumerabili di un oggetto; cioè, i nomi delle proprietà direttamente sull'oggetto e nessuno dalla catena del prototipo.

+0

Quindi, in pratica, stai dicendo che estendere i prototipi incorporati con le proprietà enumerabili è una cattiva codifica, e in un mondo pieno di codificatori perfetti sarebbe stato perfettamente legittimo usare per ... con gli array? Se è così, per esempio su prototype.js? Lo stanno facendo semplicemente storto? –

+0

@JohanHirsch ** No **, non sono ** ** dicendo che 'for ... in 'sarebbe buono da usare con gli array. Si prega di rileggere il terzo paragrafo sopra. Prototype.js era un progetto ambizioso, e penso che mentre si è trattato di un buon esperimento è una prova evidente che estendere gli oggetti di sistema non è una grande idea. Naturalmente, ora che la maggior parte degli ambienti JavaScript consente proprietà non enumerabili, forse Prototype sarebbe un problema minore. (Mi è piaciuto molto lavorare con Prototype quando lo facevo, 8 o 9 anni fa.) – Pointy

Problemi correlati