2016-05-11 14 views
5

Sono abbastanza nuovo per Javascript e cercavo di capire esattamente come funziona il ciclo for...in in base a come funziona l'operatore in.In-operatore prima e dopo cicli for-in

This risolto la confusione.

Tuttavia, ora sono confuso sul motivo per cui l'operatore in restituisce false in tutti gli scenari a parte l'ultimo.

Sembra che il ciclo for...in stia creando la chiave keyTest in obj con il valore dell'ultima iterazione.

La mia comprensione è corretta? I cicli for...in creano chiavi/valori nell'oggetto su cui si iterano quando vengono utilizzati per passare attraverso tutti gli oggetti chiavi?

Se così fosse, qualsiasi aiuto nella comprensione sarebbe di grande aiuto.

var keyTest, obj = {} 
keyTest in obj; // false 
for(var keyTest in obj) { obj[keyTest] }; 
keyTest in obj; // false 

obj = { a : 1, b : 2 }; 
keyTest in obj; // false 
for(var keyTest in obj) { obj[keyTest] }; 
keyTest in obj; // true 
obj[keyTest] // 2 
+1

'for-in' semplicemente scorre su chiavi oggetto, nient'altro. – zerkms

+0

e 'in' restituirà true se l'oggetto contiene la proprietà data. keytest e obj sono entrambi oggetti indipendenti, nessuno dei due è una proprietà dell'altro .... –

risposta

3

fare for...in anse creano chiave/valori nell'oggetto che iterare quando viene utilizzato per passare attraverso tutto un chiavi oggetti?

No, ma assegnano le chiavi alla variabile di iterazione (var keyTest nel tuo caso). Ed è per questo che i tuoi esempi producono i risultati che vedi.

// keyTest = undefined (initialisation of the hoisted variable) 
var keyTest, obj = {} // keyTest === undefined 
keyTest in obj; // keyTest === undefined 
for(var keyTest in obj) { obj[keyTest] }; // `obj` is empty and `keyTest` stays what it is 
keyTest in obj; // false // keyTest === undefined 

// keyTest = undefined (initialisation of the hoisted variable) 
obj = { a : 1, b : 2 }; // keyTest === undefined 
keyTest in obj; // keyTest === undefined 
for(var keyTest in obj) { obj[keyTest] }; // keyTest = "a", keyTest = "b" 
keyTest in obj; // keyTest === "b" 
1

Ora sono confusa sul motivo per cui l'operatore in ritorna false

in operatore accetta 2 operandi:

  • sinistra su e è il nome della chiave di testare
  • e quello di destra è l'oggetto di prova contro

Quindi, per questo frammento di codice

var keyTest, obj = {} 
keyTest in obj; // false 

il keyTest è undefined (si hanno non inizializzato con il valore). Quindi stai verificando se "undefined" (sarebbe castato in stringa, poiché gli oggetti possono * contenere solo proprietà stringa) è una delle chiavi dell'oggetto obj, che non lo è, quindi false.

for(var keyTest in obj) { obj[keyTest] }; 
keyTest in obj; // true 

Qui si restituisce true perché la variabile keyTest contiene il valore della più recente chiave iterato dopo il ciclo è stato completato. Quindi stai testando se una chiave reale è nell'oggetto.

2

Problema di sollevamento. Non esiste un ambito a livello di blocco in es5, quindi la variabile keyTest viene issata e dichiarata all'inizio dell'ambito (funzione o globale, dipende da dove viene eseguito il codice).

Quindi var keyTest non è una variabile di blocco, ma una variabile di ambito, di conseguenza fa riferimento alla stessa variabile in ogni riga del codice in cui è utilizzata in questo ambito. Ed è un motivo per cui il tuo loop for assegna a questa variabile l'ultimo valore di iterazione.


Se per parlare del tuo esempio, il motivo per cui hai due risultati diversi è che nel primo esempio non si hanno le chiavi nel vostro obj, quindi for ciclo non farà alcuna iterazione, di conseguenza non sarà assegna qualsiasi valore al tuo keyTest quindi sarà ancora indefinito.


Ma ad esempio es6 ha variabili a livello di blocco. Quindi, se si modifica var a let (parola chiave di dichiarazione a livello di blocco) nel ciclo for ed è possibile eseguire questo codice in ambiente es6-compatibile, si avrà un output diverso. Forse questo ti aiuterà a capire cosa sta succedendo.

//es6 code 
var keyTest; 
obj = { a : 1, b : 2 }; 
keyTest in obj; // false 
for(let keyTest in obj) { obj[keyTest] }; 
keyTest in obj; // false 
obj[keyTest] // undefined 
Problemi correlati