Wiem, co to jest for... in
pętla (iteruje się po kluczu), ale usłyszałem po raz pierwszy o for... of
(iteruje się po wartości).
Jestem zmieszany z for... of
pętlą. Nie dostałem przymiotnika. Oto kod poniżej:
var arr = [3, 5, 7];
arr.foo = "hello";
for (var i in arr) {
console.log(i); // logs "0", "1", "2", "foo"
}
for (var i of arr) {
console.log(i); // logs "3", "5", "7"
// it is does not log "3", "5", "7", "hello"
}
Mam for... of
iterację wartości nieruchomości. Dlaczego więc nie loguje się (nie zwraca) "3", "5", "7", "hello"
zamiast "3", "5", "7"
? ale for... in
pętla iteruje się po każdym klawiszu ( "0", "1", "2", "foo"
). for... in
Pętla tutaj również iteruje się po foo
kluczu. Ale for... of
nie przechodzi przez wartość foo
nieruchomości, tj "hello"
. Dlaczego tak jest?
Krótka historia w skrócie:
Tutaj konsola for... of
pętli. Powinien się zalogować, "3", "5", "7","hello"
ale tutaj loguje się "3", "5", "7"
. Dlaczego ?
javascript
arrays
object
Mukund Kumar
źródło
źródło
for ... of
został wprowadzony do języka, aby rozwiązać problemy z używaniemfor ... in
tablic.Array.prototype
może zostać zmieniony w taki sposób, że dostępne są dodatkowe właściwości, co sprawia, że ich iteracja jest niebezpieczna, ponieważ można uzyskać klucze nienumeryczne, których się nie spodziewałeś.of
(dla… pętli) , ponieważ pyta o konkretne zachowanie funkcji, zamiast prosić o ogólny przegląd.for <key> in
” i „for <value> of
” i zdaj sobie sprawę, że IE nie obsługujefor..of
Odpowiedzi:
for in
zapętla się nad wymiennymi nazwami właściwości obiektu.for of
(nowość w ES6) używa iteratora specyficznego dla obiektu i zapętla wartości generowane przez to.W twoim przykładzie iterator tablicy zwraca wszystkie wartości w tablicy (ignorując właściwości nieindeksowane).
źródło
for ... of
jest znormalizowany w ES6.for... of
:: tablice :: tablice zawsze mają długość, więc możesz pomyślećfor..
[n-ty element]of..
[q elementów]for..in..keys
=== klucze obce === użyjfor...in
dla kluczy! Jako takie użyjfor...of
wartości.Pełną odpowiedź znajduję na stronie : https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html (Mimo że jest to skrypt typu, to samo dotyczy javascript)
źródło
index
. I wtedy „z” będzie oznaczeniemvalues
każdego indeksu / klucza / pozycji.let thisItem = items[all];
zmienną,for...of
pomaga to skrócić!for...in
jakObject.keys()
, zgadnij co? Tablice są obiektami, które również zwracają swoje nieprzyzwoitości. :)Dla ... w pętli
Dla ... w pętli poprawia na słabości do pętli poprzez eliminację logikę liczenia i stan wyjścia.
Przykład:
Ale nadal musisz poradzić sobie z problemem korzystania z indeksu, aby uzyskać dostęp do wartości tablicy, i to śmierdzi; prawie sprawia, że jest to bardziej mylące niż wcześniej.
Pętla for ... in może sprawić kłopoty, gdy trzeba dodać dodatkową metodę do tablicy (lub innego obiektu). Ponieważ dla ... w pętlach pętla nad wszystkimi wyliczalnymi właściwościami oznacza to, że jeśli dodasz jakieś dodatkowe właściwości do prototypu tablicy, wówczas te właściwości pojawią się również w pętli.
Wydruki:
Dlatego dla ... w pętlach odradza się zapętlanie tablic.
Dla ... pętli
Dla ... od pętli jest używany do pętli nad wszelkiego rodzaju danych, które są iterable.
Przykład:
Wydruki:
To sprawia, że pętla for ... jest najbardziej zwięzłą wersją wszystkich pętli for.
Ale czekaj, jest więcej! Pętla for ... ma również dodatkowe zalety, które naprawiają słabości pętli for i for ...
W każdej chwili możesz zatrzymać lub przerwać ... pętlę.
Wydruki:
I nie musisz się martwić o dodanie nowych właściwości do obiektów. Pętla for ... zapętla tylko wartości w obiekcie.
źródło
for (var index=0; index<arr.length; index++)
pętla (gdzieindex
licznik jest liczbą całkowitą, inaczej niż w twoim przykładzie).Różnica
for..in
ifor..of
:Zarówno
for..in
ifor..of
są przelotowe konstrukcje, które są wykorzystywane do iteracji nad strukturami danych. Jedyna różnica polega na tym, co iterują:for..in
iteruje wszystkie wyliczalne klucze właściwości obiektufor..of
iteruje nad wartościami obiektu iterowalnego. Przykładami obiektów iterowalnych są tablice, łańcuchy i NodeLists.Przykład:
W tym przykładzie możemy zaobserwować, że
for..in
pętla iteruje po kluczach obiektu, który w tym przykładzie jest obiektem tablicowym. Kluczami są 0, 1, 2, które odpowiadają dodanym elementom tablicy iaddedProp
. Takarr
wygląda obiekt tablicy w chrome devtools:Widzisz, że nasza
for..in
pętla robi tylko iterację tych wartości.for..of
Pętli przykładzie iteruje się wartości w strukturze danych. Wartości w tym konkretnym przykładzie to'el1', 'el2', 'el3'
. Wartości, z których zwróci iterowalna struktura danych,for..of
zależą od typu iterowalnego obiektu. Na przykład tablica zwraca wartości wszystkich elementów tablicy, podczas gdy łańcuch zwraca każdy indywidualny znak łańcucha.źródło
for...in
Oświadczenie iteracje nad przeliczalna właściwości obiektu, w dowolnej kolejności. Wyliczalne właściwości to te właściwości, których wewnętrzna flaga [[Enumerable]] jest ustawiona na wartość true, dlatego jeśli w łańcuchu prototypów znajduje się jakaś wyliczalna właściwość,for...in
pętla również będzie iterować.for...of
Oświadczenie iteruje dane iterable obiekt określa należy powtórzyć na drugą.Przykład:
Tak jak wcześniej, możesz pominąć dodawanie
hasOwnProperty
wfor...of
pętlach.źródło
Instrukcja for-in iteruje po policzalnych właściwościach obiektu w dowolnej kolejności.
Pętla będzie iterować wszystkie wyliczalne właściwości samego obiektu i tych, które dziedziczy po prototypie konstruktora
Możesz myśleć o tym jako o „na wejściu” w zasadzie iteruje i wypisuje wszystkie klucze.
źródło
for in
pokaże klucze tylko jeśli zostaną przez nas dodane, nie wyświetli formatu JednorożecString.prototype
.Istnieją już zdefiniowane typy danych, które pozwalają na łatwe iterowanie nad nimi, np. Array, Map, String Objects
Normalne dla iteracji nad iteratorem iw odpowiedzi dostarcza nam klucze, które są w kolejności wstawiania, jak pokazano w poniższym przykładzie.
Teraz, jeśli spróbujemy tego samego z for , to w odpowiedzi dostarczy nam wartości, a nie klucze. na przykład
Patrząc na oba iteratory, możemy łatwo odróżnić różnicę między nimi.
Więc jeśli spróbujemy wykonać iterację nad normalnym obiektem, to da nam błąd, np.
Teraz w celu iteracji musimy zdefiniować ES6 Symbol.iterator np
To jest różnica między For in a For of . Mam nadzieję, że to wyjaśni różnicę.
źródło
Kolejna różnica między dwiema pętlami, o której nikt wcześniej nie wspominał:
Źródło
Więc jeśli chcemy użyć destrukcji w pętli, w celu uzyskania zarówno indeksu, jak i wartości każdego elementu tablicy , powinniśmy użyć
for...of
pętli z metodą Arrayentries()
:źródło
for each...in
jest przestarzałe (pierwszy punkt), ale nie pisałem o tym ... Napisałem, że „Destrukturyzacjafor...in
jest przestarzała. Użyjfor...of
zamiast tego”. (drugi punkt): developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Czy zgadzasz się ze mną @GalMargalit?Wszyscy wyjaśnili, dlaczego ten problem występuje, ale nadal bardzo łatwo o nim zapomnieć, a następnie podrapać się w głowę, dlaczego otrzymałeś złe wyniki. Zwłaszcza, gdy pracujesz nad dużymi zestawami danych, gdy wyniki wydają się na pierwszy rzut oka dobre.
Za pomocą
Object.entries
upewnij się, aby przejść przez wszystkie właściwości:źródło
Widzę wiele dobrych odpowiedzi, ale postanawiam postawić moje 5 centów, aby mieć dobry przykład:
Do pętli
iteruje wszystkie wyliczalne rekwizyty
For of loop
iteruje wszystkie wartości iterowalne
źródło
Kiedy po raz pierwszy zacząłem uczyć się pętli for in i loop , byłem również zdezorientowany z moją wydajnością, ale z kilkoma badaniami i zrozumieniem możesz pomyśleć o indywidualnej pętli w następujący sposób:
let profile = { name : "Naphtali", age : 24, favCar : "Mustang", favDrink : "Baileys" }
Powyższy kod tworzy tylko obiekt o nazwie profil , użyjemy go w obu naszych przykładach , więc nie myl się, gdy zobaczysz obiekt profilu na przykładzie, po prostu wiedz, że został utworzony.
dla ... pętli * może zwrócić właściwość , wartość lub oba , Spójrzmy jak. W javaScript nie możemy normalnie zapętlać obiektów, tak jak w przypadku tablic, więc istnieje kilka elementów, których możemy użyć, aby uzyskać dostęp do jednego z naszych wyborów z obiektu.
Object.keys ( nazwa-obiektu-idzie-tutaj ) >>> Zwraca klucze lub właściwości obiektu.
Object.values ( nazwa-obiektu-idzie-tutaj ) >>> Zwraca wartości obiektu.
Poniżej znajdują się przykłady ich użycia, zwróć uwagę na Object.entries () :
źródło
for-in
pętlafor-in
Pętla służy do przechodzenia przez wyliczalne właściwości kolekcji w dowolnej kolejności . Kolekcja to obiekt typu kontener, którego elementy mogą korzystać z indeksu lub klucza.for-in
Pętla wyodrębnia wszystkie wyliczalne właściwości ( klucze ) kolekcji naraz i iteruje po niej pojedynczo. Wyliczalna właściwość jest właściwością kolekcji, która może pojawiać się wfor-in
pętli.Domyślnie wszystkie właściwości macierzy i obiektu pojawiają się w
for-in
pętli. Możemy jednak użyć metody Object.defineProperty , aby ręcznie skonfigurować właściwości kolekcji.W powyższym przykładzie, własność
d
zmyObject
a wskaźnik3
zmyArray
nie pojawia się wfor-in
pętli, ponieważ są one skonfigurowaneenumerable: false
.Istnieje kilka problemów z
for-in
pętlami. W przypadku tablicfor-in
pętla będzie również rozważaćmethods
dodanie do tablicy przy użyciumyArray.someMethod = f
składni, jednakmyArray.length
pozostaje4
.for-of
pętlaJest to nieporozumienie, które
for-of
powtarza iterację wartości kolekcji.for-of
pętla iterujeIterable
obiekt. Iterowalny to obiekt, który ma metodę z nazwąSymbol.iterator
bezpośrednio na niej na jednym ze swoich prototypów.Symbol.iterator
Metoda powinna zwrócić Iterator . Iterator to obiekt posiadającynext
metodę. Ta metoda nazywa się returnvalue
idone
właściwości.Kiedy iterujemy iterowalny obiekt za pomocą
for-of
pętli,Symbol.iterator
metoda zostanie wywołana, gdy otrzymamy obiekt iteratora . Dla każdej iteracjifor-of
pętli,next
metoda tego obiektu iteratora zostanie wywołana ażdone
zwrócony przeznext()
fałszywe deklaracje połączeń. Wartość otrzymywana przezfor-of
pętlę dla każdej iteracji, jeślivalue
właściwość zwrócona przeznext()
wywołanie.for-of
Pętla jest nowy w ES6 i tak są iterable i Iterables . TypArray
konstruktora maSymbol.iterator
metodę na swoim prototypie.Object
Konstruktor niestety nie ma go jednakObject.keys()
,Object.values()
aObject.entries()
metody zwracać iterable ( można użyćconsole.dir(obj)
w celu sprawdzenia metody prototypów ). Zaletąfor-of
pętli jest to, że każdy obiekt może być iterowalny, nawet twój niestandardowyDog
iAnimal
klasy.Najłatwiejszym sposobem, aby obiekt był iterowalny, jest implementacja Generatora ES6 zamiast niestandardowej implementacji iteratora.
W przeciwieństwie do tego
for-in
,for-of
pętla może czekać na zakończenie zadania asynchronicznego w każdej iteracji. Osiąga się to za pomocąawait
słowa kluczowego po dokumentacjifor
instrukcji .Kolejną wielką zaletą
for-of
pętli jest obsługa Unicode. Zgodnie ze specyfikacjami ES6, ciągi są przechowywane z kodowaniem UTF-16. Stąd, każda postać może przybrać jedną16-bit
lub32-bit
. Tradycyjnie ciągi były przechowywane z kodowaniem UCS-2, które obsługuje znaki, które można przechowywać16 bits
tylko w obrębie .Dlatego
String.length
zwraca liczbę16-bit
bloków w ciągu. Nowoczesne postacie, takie jak znak Emoji, mają 32 bity. Dlatego znak ten zwrócilength
2.for-in
pętlę, iteruje się po16-bit
blokach i zwraca błądindex
. Jednakfor-of
pętla iteruje indywidualny znak na podstawie specyfikacji UTF-16.źródło
Bardzo pomocne okazało się następujące wyjaśnienie z https://javascript.info/array :
Jednym z najstarszych sposobów przełączania elementów tablicy jest indeksowanie pętli for:
Technicznie, ponieważ tablice są obiektami, możliwe jest również użycie dla ... w:
Pętla dla ... in iteruje wszystkie właściwości, nie tylko numeryczne.
W przeglądarce i innych środowiskach znajdują się tak zwane „tablicowe” obiekty, które wyglądają jak tablice. Oznacza to, że mają właściwości długości i indeksów, ale mogą także mieć inne właściwości nienumeryczne i metody, których zwykle nie potrzebujemy. Pętla for..in wyświetli je jednak. Jeśli więc musimy pracować z obiektami podobnymi do tablicy, te „dodatkowe” właściwości mogą stać się problemem.
Pętla for..in jest zoptymalizowana dla obiektów ogólnych, a nie tablic, a zatem jest 10–100 razy wolniejsza. Oczywiście nadal jest bardzo szybki. Przyspieszenie może mieć znaczenie tylko w wąskich gardłach. Ale nadal powinniśmy być świadomi różnicy.
Zasadniczo nie powinniśmy używać dla ... w przypadku tablic.
źródło
Oto przydatny mnemonik do zapamiętywania różnicy między
for...in
pętlą afor...of
pętlą.„indeksuj, obiekt”
for...in Loop
=> iteruje po indeksie w tablicy.for...of Loop
=> iteruje po obiekcie obiektów.źródło