2016-05-11 30 views
5

Jestem całkiem nowym użytkownikiem Javascript i starałem się dokładnie zrozumieć, jak działa pętla for...in w oparciu o działanie operatora in.In-operator przed i po pętli for-in

This wyjaśnił zamieszanie.

Jednak jestem teraz zdezorientowany, dlaczego operator in zwraca false we wszystkich scenariuszach oprócz ostatniego.

Wygląda na to, że pętla for...in tworzy klucz keyTest w obj z wartością ostatniej iteracji.

Czy moje zrozumienie jest prawidłowe? Czy pętle for...in tworzą klucze/wartości w obiekcie, który iterują, gdy są używane do przechodzenia przez wszystkie klucze obiektów?

Jeśli tak, pomoc w zrozumieniu naprawdę pomoże.

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' po prostu iteruje po kluczach obiektów, nic więcej. – zerkms

+0

i 'in' zwróci wartość true, jeśli obiekt zawiera daną właściwość. keytest i obj są obiektami niezależnymi, żaden nie jest własnością innego ... –

Odpowiedz

3

Czy for...in pętle utworzyć klucz/wartość w obiekcie one iteracyjnego gdy wykorzystywane, aby przejść przez wszystkie an obiektów kluczy?

Nie, ale przypisują klucze do zmiennej iteracyjnej (var keyTest w twoim przypadku). I dlatego Twoje przykłady dają wyniki, które widzisz.

// 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

Jestem teraz mylić, dlaczego operator in zwróci false

in operator przyjmuje 2 argumenty:

  • pozostawione na e jest kluczem nazwa przetestować
  • a prawy jest obiektem do badań przed

Więc na ten fragment kodu

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

keyTest jest undefined (nie masz zainicjowany go wartość). Sprawdzasz, czy "undefined" (zostałoby to rzucone na ciąg, ponieważ obiekty mogą * tylko utrzymywać właściwości ciągu) jest jednym z kluczy obiektów obj, który nie jest, a więc false.

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

Tu zwraca true ponieważ zmienna keyTest przechowuje wartość najnowszej klucza powtórzyć po pętla zostanie zakończona. Sprawdzasz, czy w obiekcie znajduje się prawdziwy klucz.

2

To kwestia podnoszenia. W wersji es5 nie ma zakresu blokowego, więc zmienna keyTest jest podnoszona i zadeklarowana na początku zakresu (funkcja lub globalna, zależy od tego, gdzie uruchamiasz swój kod).

Tak więc var keyTest nie jest zmienną blokową, ale zmienną zasięgu, dlatego też odnosi się do tej samej zmiennej w każdym wierszu kodu, w którym jest używany w tym zakresie. I to jest powód, dla którego twoja pętla for przypisuje ostatniej wartości iteracji do tej zmiennej.


Jeśli mówić o swoim przykładzie, dlatego masz dwa różne wyniki, że w pierwszym przykładzie nie masz klucze w swojej obj, więc for pętla nie wykona żadnej iteracji, odpowiednio nie będzie przypisz dowolną wartość do twojego keyTest, więc nadal będzie niezdefiniowana.


Ale na przykład es6 ma zmienne blokowe. Więc jeśli zmienisz var na let (słowo kluczowe deklaracji zmiennej blokowej) w twojej pętli for i uruchomisz ten kod w środowisku zgodnym z es6, będziesz miał różne wyniki. Może to pomoże ci zrozumieć, co się dzieje.

//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