Promjena vanjske varijable pomoću js petlje. For petlje u JavaScriptu

To se uvlačenje može smatrati pokazateljem složenosti koda (iako prilično grubim). Uvlake su same po sebi neutralne, jer su samo sredstvo za oblikovanje teksta, ali cijela je stvar u tome što se koriste za označavanje posebnih blokova programa, na primjer, kontrolnih struktura. Kada čita kod i naiđe na uvlačenje, programer je prisiljen uzeti u obzir što uvlačenje označava, imati na umu kontekst u kojem postoji odabrani blok. To se, naravno, ponavlja ako se u uvučenom odjeljku koda pojavi još jedan poseban fragment.

Ako ne obraćate pažnju na sadržaj tekstova, onda ovako obično izgleda složeni kod čiji dijelovi izgledaju kao slova “V” koja leže sa strane i jednostavan kod čiji blok, ako ne uzimajući u obzir različite duljine linija, izgleda kao pravokutnik.


Što je više uvlaka, to je kod obično složeniji.

Konstrukti koje treba uvući uvijek će biti u kodu; nema govora o tome da ih se potpuno riješite. Međutim, imamo moć smanjiti složenost programa koje pišemo racionalnim odabirom apstrakcija za rješavanje problema s kojima se suočavamo.

Uzmimo za primjer nizove. Tradicionalno se za njihovu obradu koriste različite vrste ciklusa. Koncepti "niza" i "petlje" neraskidivo su povezani u glavama mnogih programera. Međutim, ciklus je vrlo dvosmislena konstrukcija. Evo što Louis Atentzio piše o petljama u svojoj knjizi Funkcionalno programiranje u JavaScriptu: “Petlja je čvrsta kontrolna konstrukcija koju nije lako ponovno upotrijebiti i koju je teško integrirati s drugim operacijama. Također, korištenje petlji znači stvaranje koda koji se mijenja sa svakom iteracijom."


Je li moguće riješiti se ciklusa?

Ciklus je jedna od glavnih strukturnih kontrolnih struktura i, zapravo, nećemo reći da su ciklusi zlo kojeg se treba riješiti. Naš glavni cilj je smanjiti složenost vlastitog koda minimiziranjem upotrebe petlji pri obradi nizova. Je li moguće? Pozivamo vas da zajedno saznamo.

Ciklusi

Već smo govorili o tome kako kontrolne konstrukcije poput petlji dodaju složenost vašem kodu. Ali zašto je to tako? Pogledajmo kako petlje rade u JavaScriptu.

Postoji nekoliko načina organiziranja petlji u JS-u. Konkretno, jedna od osnovnih vrsta petlji je while. Prije nego što uđemo u detalje, pripremimo se malo. Naime, napravit ćemo funkciju i niz s kojim ćemo raditi.

// oodlify:: String -> Funkcija niza oodlify(s) ( return s.replace(//g, "oodle"); ) const input = [ "John", "Paul", "George", "Ringo", ];
Dakle, imamo niz čiji ćemo svaki element obraditi pomoću funkcije oodlify. Ako koristite while petlju za rješavanje ovog problema, dobit ćete sljedeće:

Neka je i = 0; const len ​​​​= input.length; neka izlaz = ; dok ja< len) { let item = input[i]; let newItem = oodlify(item); output.push(newItem); i = i + 1; }
Imajte na umu da koristimo i brojač da pratimo trenutno obrađen element niza. Mora se inicijalizirati na nulu i povećati za jedan u svakoj iteraciji petlje. Osim toga, trebate ga usporediti s duljinom niza, s len, kako biste znali kada prestati raditi.

Ovaj obrazac je toliko uobičajen da JavaScript ima lakši način za to: for petlju. Takva petlja će riješiti isti problem na sljedeći način:

Const len ​​​​= input.length; neka izlaz = ; za (neka je i = 0; i< len; i = i + 1) { let item = input[i]; let newItem = oodlify(item); output.push(newItem); }
Petlja for je korisna konstrukcija jer stavlja sve standardne pomoćne operacije brojača gornji dio blok. Koristeći while, lako je zaboraviti na potrebu povećanja brojača i, što će dovesti do beskonačne petlje. For petlja je definitivno mnogo praktičnija od while petlje. Ali usporimo i pogledajmo što naš kod pokušava postići. Želimo obraditi, pomoću funkcije oodlify(), svaki element niza i staviti rezultat u novi niz. Sam brojač, koji se koristi za pristup elementima niza, nas ne zanima.

Ovaj obrazac rada s nizovima, koji uključuje izvođenje određenih radnji na svakom elementu, vrlo je čest. Kao rezultat toga, ES2015 je predstavio novi dizajn petlje koji vam omogućuje da zaboravite na brojač. Ovo je for…of petlja. Svaka iteracija ove petlje daje sljedeći element niza. Ovako izgleda:

Neka je izlaz = ; za (neka stavka unosa) ( neka novaStavka = oodlify(stavka); izlaz.push(novaStavka); )
Kod izgleda mnogo čistije. Imajte na umu da ne postoji operacija brojanja ili usporedbe. S ovim pristupom, ne morate čak ni pristupiti određenom elementu niza prema indeksu. For…of petlja se brine za sve pomoćne operacije.

Ako dovršimo našu studiju o načinima rada s nizovima i posvuda koristimo for…of petlje umjesto for petlji, to će već biti dobar korak naprijed pojednostavljivanjem koda. Ali... možemo i dalje.

Transformacija nizova

Petlja for…of izgleda mnogo čistije od petlje for, ali također ima puno pomoćnih elemenata u kodu. Dakle, trebate inicijalizirati izlazni niz i pozvati metodu push() u svakoj iteraciji petlje. Kod se može učiniti još kompaktnijim i izražajnijim, ali prije nego što to učinimo, proširimo malo demo problem. Što ako morate obraditi dva niza pomoću funkcije oodlify()?

Const fellowship = [ "frodo", "sam", "gandalf", "aragorn", "boromir", "legolas", "gimli", ]; const band = [ "John", "Paul", "George", "Ringo", ];
Potpuno očito rješenje je koristiti dvije petlje i obraditi nizove u njima:

Neka bandoodle = ; for (let item of band) ( let newItem = oodlify(item); bandoodle.push(newItem); ) let floodleship = ; za (neka stavka zajedništva) ( neka newItem = oodlify(item); floodleship.push(newItem); )
Sasvim radna opcija. A kod koji radi puno je bolji od koda koji ne rješava problem koji mu je dodijeljen. Ali dva vrlo slična dijela koda ne uklapaju se osobito dobro u DRY princip dizajna softvera. Kod se može refaktorirati kako bi se smanjilo ponavljanje.

Slijedeći ovu ideju, kreiramo sljedeću funkciju:

Funkcija oodlifyArray(input) ( let output = ; for (let item of input) ( let newItem = oodlify(item); output.push(newItem); ) return output; ) let bandoodle = oodlifyArray(band); let floodleship = oodlifyArray(fellowship);
Ovo izgleda puno bolje, ali što ako postoji još jedna funkcija s kojom također želimo obraditi elemente niza?

Funkcija izzlify(s) ( return s.replace(/+/g, "izzle"); )
Sada funkcija oodlifyArray() neće pomoći. Međutim, ako stvorimo drugu sličnu funkciju, ovaj put izzlufyArray() , opet ćemo se ponoviti. Ipak, stvorimo takvu funkciju i usporedimo je s oodlifyArray() :

Funkcija oodlifyArray(input) ( let output = ; for (let item of input) ( let newItem = oodlify(item); output.push(newItem); ) return output; ) function izzlifyArray(input) ( let output = ; for ( let item of input) ( let newItem = izzlify(item); output.push(newItem); ) return output; )
Dvije su funkcije nevjerojatno slične. Možda možemo sažeti obrazac koji slijede? Naš cilj je sljedeći: “Imamo niz i funkciju. Moramo dobiti novi niz u koji će biti upisani rezultati obrade svakog elementa izvornog niza pomoću funkcije.” Ova metoda obrade nizova naziva se "preslikavanje" ili "transformacija" (preslikavanje u engleskoj terminologiji). Funkcije koje izvode takve operacije obično se nazivaju "map". Ovako izgleda naša verzija takve funkcije:

Funkcijska mapa(f, a) ( let output = ; for (let item of a) ( output.push(f(item)); ) return output; )
Iako je petlja sada zasebna funkcija, nije je se bilo moguće potpuno riješiti. Ako idete do kraja i pokušate u potpunosti bez cikličkih konstrukcija, možete napisati rekurzivnu verziju iste stvari:

Funkcija map(f, a) (if (a.length === 0) ( return ; ) return .concat(map(f, a.slice(1))); )
Rekurzivno rješenje izgleda vrlo elegantno. Samo nekoliko redaka koda i minimalno uvlačenje. Ali rekurzivne implementacije algoritama obično se koriste s velikim oprezom, a također pate od loše izvedbe u starijim preglednicima. I, zapravo, zapravo ne trebamo napisati funkciju za implementaciju operacije mapiranja sami, osim ako postoji dobar razlog za to. Ono što radi naša funkcija karte toliko je uobičajen zadatak da JavaScript ima ugrađenu metodu map(). Ako koristite ovu metodu, kôd će izgledati ovako:

Neka bandoodle = band.map(oodlify); let floodleship = zajedništvo.map(oodlify); let bandizzle = band.map(izzlify); neka zajedništvo = zajedništvo.map(izzlify);
Primijetite da uopće nema udubljenja ili petlje. Naravno, prilikom obrade podataka, negdje u dubinama JavaScripta, mogu se koristiti petlje, ali to više nije naša briga. Sada je kod i sažet i izražajan. Štoviše, jednostavnije je.

Zašto je ovaj kod jednostavniji? Ovo se možda čini kao glupo pitanje, ali razmislite o tome. Je li jednostavnije jer je kraće? Ne. Kompaktan kod nije znak jednostavnosti. Jednostavnije je jer smo ovim pristupom problem razbili na dijelove. Naime, dvije su funkcije koje rade sa stringovima: oodlify i izzlify. Ove funkcije ne moraju znati ništa o nizovima ili petljama. Postoji još jedna funkcija - karta, koja radi s nizovima. Istovremeno, potpuno je svejedno koja se vrsta podataka nalazi u nizu ili što točno želimo učiniti s tim podacima. Jednostavno izvršava bilo koju funkciju koja mu je proslijeđena, prosljeđujući joj elemente niza. Umjesto da sve miješamo, odvojili smo obradu nizova i obradu nizova. Zato se konačni kod pokazao jednostavnijim.

Konvolucija niza

Dakle, funkcija karte je vrlo korisna, ali ne pokriva sve opcije obrade polja koje koriste petlje. Dobar je u slučajevima kada na temelju određenog niza trebate kreirati novi iste duljine. Ali što ako trebamo, na primjer, zbrojiti sve elemente numeričkog niza? Ili što ako trebate pronaći najkraći niz na popisu? Ponekad morate obraditi niz i zapravo generirati jednu vrijednost na temelju njega.

Pogledajmo primjer. Recimo da imamo popis objekata od kojih svaki predstavlja superheroja:

Const heroes = [ (ime: "Hulk", snaga: 90000), (ime: "Spider-Man", snaga: 25000), (ime: "Sokolovo oko", snaga: 136), (ime: "Thor", snaga: 100000), (ime: "Crna udovica", snaga: 136), (ime: "Vizija", snaga: 5000), (ime: "Grimizna vještica", snaga: 60), (ime: "Mystique", snaga: 120), (naziv: "Namora", snaga: 75000), ];
Moramo pronaći najjačeg heroja. Da biste to učinili, možete koristiti for…of petlju:

Neka je najjači = (snaga: 0); za (neka junak nad junacima) ( ako (junak.snaga > najjača.snaga) ( najjači = junak; ) )
Kad se sve uzme u obzir, ovaj kod i nije tako loš. Prolazimo nizom, pohranjujući objekt najjačeg heroja kojeg smo gledali u najjačoj varijabli. Kako bismo jasnije vidjeli obrazac rada s nizom, zamislimo da moramo saznati i ukupnu snagu svih heroja.

Neka jointStrength = 0; za (neka heroj nad herojima) (combinedStrength += hero.strength; )
U svakom od ova dva primjera postoji radna varijabla koja se inicijalizira prije pokretanja petlje. Zatim se u svakoj iteraciji obrađuje jedan element niza i ažurira se varijabla. Kako bismo još bolje istaknuli shemu rada, operacije koje se izvode unutar petlji premjestit ćemo u funkcije, a varijable preimenovati kako bismo naglasili sličnost radnji koje se izvode.

Funkcija largeStrength(champion, contender) ( return (contender.strength > šampion.strength) ? contender: prvak; ) function addStrength(tally, hero) ( return zbroj + hero.strength; ) const initial Najjači = (snaga: 0); neka radi = početni Najjači; za (heroj heroja) (radni = većaSnaga(radni, heroj); ) const najjači = radni; const initialCombinedStrength = 0; radna = početnaKombiniranaSnaga; za (heroj heroja) (working = addStrength(working, hero); ) const combinationStrength = work;
Ako se sve prepiše kao što je gore prikazano, dvije petlje na kraju su vrlo slične. Jedina stvar koja ih razlikuje su funkcije koje se u njima pozivaju i početne vrijednosti varijabli. U obje petlje niz se sažima na jednu vrijednost. U engleskoj terminologiji takva se operacija naziva "reducing". Stoga ćemo stvoriti funkciju redukcije koja implementira otkriveni uzorak.

Funkcija smanji(f, početnaVal, a) ( neka radi = početnaVal; for (pusti stavka od a) ( radi = f(radna, stavka); ) vrati radi; )
Treba napomenuti da je, kao i s uzorkom funkcije karte, obrazac funkcije reduciranja toliko raširen da ga JavaScript nudi kao ugrađenu metodu niza. Stoga, osim ako za to ne postoji poseban razlog, nema potrebe pisati vlastitu metodu. Korištenjem standardne metode kod bi izgledao ovako:

Const najjačiHero = heroes.reduce(greaterStrength, (snaga: 0)); const jointStrength = heroes.reduce(addStrength, 0);
Ako bolje pogledate konačni rezultat, vidjet ćete da rezultirajući kod nije puno kraći od onoga što je bio prije, uštede su vrlo male. Da smo koristili reducirajuću funkciju, koju smo sami napisali, tada bi općenito kod bio veći. Međutim, naš cilj nije napisati kratki kod, već smanjiti njegovu složenost. Dakle, jesmo li smanjili složenost programa? Mogu reći da su smanjili. Odvojili smo kod za ponavljanje od koda koji obrađuje elemente niza. Time su pojedini dijelovi programa postali samostalniji. Kod se pokazao jednostavnijim.

Na prvi pogled funkcija redukcije može izgledati prilično primitivno. Većina primjera ove funkcije pokazuje jednostavne stvari poput zbrajanja svih elemenata numeričkih nizova. Međutim, nigdje se ne kaže da vrijednost koja smanjuje prinose mora biti primitivnog tipa. To može biti objekt ili čak neki drugi niz. Kad sam to prvi put shvatio, zapanjilo me. Možete, na primjer, napisati implementaciju operacije preslikavanja niza ili filtriranja koristeći smanjivanje. Predlažem da sami isprobate.

Filtriranje nizova

Dakle, postoji funkcija karte za izvođenje operacija na svakom elementu niza. Postoji funkcija reduciranja koja vam omogućuje komprimiranje niza na jednu vrijednost. Ali što ako trebate izdvojiti samo neke od elemenata iz niza? Kako bismo istražili ovu ideju, proširimo popis superheroja i dodamo neke dodatne podatke:

Const heroes = [ (ime: "Hulk", snaga: 90000, spol: "m"), (ime: "Spider-Man", snaga: 25000, spol: "m"), (ime: "Sokolovo oko", snaga: 136, spol: "m"), (ime: "Thor", snaga: 100000, spol: "m"), (ime: "Crna udovica", snaga: 136, spol: "f"), (ime : "Vizija", snaga: 5000, spol: "m"), (ime: "Grimizna vještica", snaga: 60, spol: "f"), (ime: "Mystique", snaga: 120, spol: "f "), (ime: "Namora", snaga: 75000, spol: "f"), ]);
Sada pretpostavimo da postoje dva problema:

  1. Pronađite sve ženske heroje.
  2. Pronađite sve heroje čija moć prelazi 500.
Sasvim je moguće pristupiti rješenju ovih problema korištenjem dobre stare for…of petlje:

Neka femaleHeroes = ; for (neka heroj heroja) ( if (hero.sex === "f") ( femaleHeroes.push(hero); ) ) let superhumans = ; za (neka heroj nad herojima) ( if (hero.strength >= 500) ( superhumans.push(hero); ) )
Općenito, izgleda sasvim pristojno. Ali ovdje je golim okom vidljiv uzorak koji se ponavlja. Zapravo, petlje su potpuno iste, razlikuju se samo u if blokovima. Što ako te blokove stavimo u funkcije?

Funkcija isFemaleHero(hero) ( return (hero.sex === "f"); ) function isSuperhuman(hero) ( return (hero.strength >= 500); ) let femaleHeroes = ; for (neka heroj heroja) ( if (isFemaleHero(hero)) ( femaleHeroes.push(hero); ) ) let superhumans = ; za (neka heroj heroja) ( if (isSuperhuman(hero)) ( superhumans.push(hero); ) )
Funkcije koje vraćaju samo true ili false ponekad se nazivaju predikatima. Koristimo predikat da odlučimo hoćemo li sljedeću vrijednost iz niza heroja pohraniti u novi niz.

Način na koji smo prepisali kod učinio ga je dužim. No, nakon isticanja predikatnih funkcija, dijelovi programa koji se ponavljaju postali su bolje vidljivi. Kreirajmo funkciju koja će nam omogućiti da se riješimo ovih ponavljanja:

Funkcija filter(predikat, arr) ( neka radi = ; for (let item of arr) ( if (predikat(item)) (working = working.concat(item); ) ) return work; ) const femaleHeroes = filter(isFemaleHero, heroji); const superhumans = filter(isSuperhuman, heroji);
Ovdje, kao i kod ugrađenih funkcija mapiranja i reduciranja, JavaScript ima istu stvar koju smo ovdje napisali u obliku standardne metode filtra na objektu Array. Stoga, nema potrebe da pišete vlastitu funkciju osim ako to nije neophodno. Korištenje standardnim sredstvima kod će izgledati ovako:

Const femaleHeroes = heroes.filter(isFemaleHero); const superhumans = heroes.filter(isSuperhuman);
Zašto je ovaj pristup puno bolji od upotrebe za petlju... od ? Razmislite kako to možete iskoristiti u praksi. Imamo zadatak poput: “Pronađi sve heroje koji...”. Nakon što shvatite da možete riješiti problem korištenjem standardne funkcije filtra, posao postaje lakši. Sve što trebamo učiniti je reći ovoj funkciji koji elementi nas zanimaju. To se postiže pisanjem jedne kompaktne funkcije. Nema potrebe brinuti se o obradi nizova ili dodatnih varijabli. Umjesto toga, napišemo sićušnu predikativnu funkciju i problem je riješen.

Kao i kod drugih funkcija koje rade s nizovima, korištenje filtra omogućuje vam da izrazite više informacija u manje koda. Nema potrebe čitati cijelu stvar standardni kod petlju kako bismo razumjeli što točno filtriramo. Umjesto toga, sve što trebate razumjeti opisano je odmah kada se metoda pozove.

Pretraživanje u nizovima

Filtriranje je vrlo korisna operacija. Ali što ako trebate pronaći samo jednog superheroja s popisa? Recimo da nas zanima Black Widow. Funkcija filtra može se koristiti za rješavanje ovog problema:

Funkcija isBlackWidow(hero) ( return (hero.name === "Crna udovica"); ) const blackWidow = heroes.filter(isBlackWidow);
Glavni problem ovdje je što takvo rješenje nije učinkovito. Metoda filtra prolazi kroz svaki element niza. Međutim, poznato je da se u nizu samo jedan heroj zove Black Widow, što znači da možete stati nakon što se taj heroj pronađe. U isto vrijeme, predikat funkcije su prikladne za korištenje. Stoga, napišimo funkciju traženja koja će pronaći i vratiti prvi odgovarajući element:

Funkcija find(predikat, arr) ( for (let item of arr) ( if (predikat(item)) ( return item; ) ) ) const blackWidow = find(isBlackWidow, heroes);
Ovdje se opet mora reći da JavaScript ima ugrađenu funkciju koja radi točno ono što je potrebno:

Const blackWidow = heroes.find(isBlackWidow);
Kao rezultat toga, mogli smo konciznije izraziti svoju ideju. Koristeći ugrađenu funkciju traženja, zadatak traženja određenog elementa svodi se na jedno pitanje: "Prema kojim kriterijima možemo utvrditi da je željeni element pronađen?" Ne morate brinuti o detaljima.

O funkcijama smanjenja i filtriranja

Čitatelji su primijetili da je neučinkovito ponavljati popis heroja dvaput u gornjim primjerima za funkcije reduciranja i filtriranja. Korištenje operatora širenja iz ES2015 omogućuje vam praktično kombiniranje dviju funkcija presavijanja niza u jednu. Evo modificiranog dijela koda koji vam omogućuje ponavljanje niza samo jednom:

Funkcija processStrength((najjačiHero, kombiniranaSnaga), hero) ( return ( jačiHero: većaSnaga(najjačiHero, heroj),kombiniranaSnaga: addSnaga(kombiniranaSnaga, heroj), ); ) const (najjačiHero,kombiniranaSnaga) = heroes.reduce(processStrength, (najjačiHeroj) : (snaga: 0), kombinirana snaga: 0));
Ne mogu a da ne primijetim da će ova verzija biti malo kompliciranija od one u kojoj je niz prošao dva puta, ali ako je niz ogroman, smanjenje broja prolaza preko njega može biti vrlo korisno. U svakom slučaju redoslijed složenosti algoritma ostaje O(n).

Rezultati

Mislim da su ovdje predstavljene značajke izvrstan primjer zašto su promišljeno odabrane apstrakcije korisne i izgledaju dobro u kodu. Recimo da koristimo ugrađene funkcije gdje god je to moguće. U svakom slučaju slijedeći rezultati:
  1. Riješimo se petlji, što kod čini sažetijim i najvjerojatnije lakšim za čitanje.
  2. Korišteni predložak opisan je korištenjem prikladnog standardnog naziva metode. Odnosno, mapirajte, smanjite, filtrirajte ili pronađite.
  3. Smanjen je opseg zadatka. Umjesto da sami pišete kod za obradu niza, samo trebate reći standardnoj funkciji što da radi s nizom.
Imajte na umu da se u svakom slučaju za rješavanje problema koriste kompaktne čiste funkcije.

Zapravo, ako razmislite o svemu ovome, možete doći do zaključka koji na prvu djeluje iznenađujuće. Ispostavilo se da ako koristite samo četiri gore opisana uzorka obrade polja, možete ukloniti gotovo sve petlje iz svog JS koda. Uostalom, što se radi u gotovo svakoj petlji napisanoj u JavaScriptu? On ili obrađuje ili konstruira određeni niz, ili radi oboje. Osim toga, JS ima i druge standardne funkcije za rad s nizovima, koje možete lako naučiti sami. Uklanjanje petlji gotovo uvijek smanjuje složenost programa i piše kod koji je lakši za čitanje i održavanje.

Dragi JavaScript programeri, imate li na umu neke standardne funkcije koje mogu poboljšati kod uklanjanjem nekih uobičajenih "domaćih" konstrukcija?

Oznake: Dodajte oznake

For petlja je najčešće korištena petlja u JavaScriptu.

Njegov dizajn izgleda ovako:

Za (početak; uvjet; korak) ( /* tijelo petlje */ )

Stvarno je jednostavno. Pogledajmo primjer:

Var i; za (i = 1; i

U ovom primjeru:

  • Početak ciklusa: i = 1 (počevši od vrijednosti i = 1)
  • Stanje ciklusa:i
  • Ciklusni korak: i++ (u svakom koraku petlje i se povećava za 1)
  • Tijelo petlje:document.write("

    Izvršava se broj koraka ciklusa: " + "

    "); (prikazati poruku na ekranu)

Algoritam korak po korak za izvođenje ove for petlje, detaljnije:

  1. Početak petlje: varijabla i je postavljena na 1. Ovaj dio petlje se izvodi jednom.
  2. Provjerava se uvjet petlje (i 5) - kraj petlje.
  3. Izvršava se tijelo petlje.
  4. Korak petlje je izvršen. U našem slučaju i++. Uvijek se izvršava nakon tijela petlje.
  5. Povratak na točku 2.

Ako se tijelo petlje sastoji od jedne instrukcije, tada su vitičaste zagrade {...} nije ga potrebno staviti.

Varijabla i ne nestaje nakon završetka petlje. On nastavlja postojati i njegova će vrijednost nakon završetka ciklusa biti jednaka 6.

Sažmimo ove podatke u novom primjeru:

Var i; za (i = 1; i

Ovdje se vitičaste zagrade nisu koristile za stvaranje tijela petlje.

Proteza za zube {...} oblikuju blok u JavaScriptu - ovo je jedna od jezičnih konstrukcija. Odnosno, ako postoje vitičaste zagrade nakon naredbe petlje for, to znači da JavaScript rukovatelj mora izvršiti cijeli JavaScript blok.

Slično bloku, možete navesti funkciju u for petlji. Evo primjera:

Za (var i = 1; i

Ali kada se deklarira funkcija, postoje vitičaste zagrade {...} potreban. Njihov nedostatak rezultirat će greškom.

Imajte na umu da je u ovoj petlji varijabla i deklarirana na početku petlje: for ( var i = 1; ja

Preskakanje dijelova

Općenito, početak ciklusa ne treba pisati:

Var i = 1; za(;i

Vidite, na početku petlje postoji samo točka-zarez, a petlja radi dobro.

Također možete ukloniti korak:

Var i = 1; za(;i

Ova for petlja se pretvorila u analognu while petlji (tj

Možete staviti izraz u uvjet koji mijenja varijablu.

Za (i = 10; i--;) (document.write("

Izvršava se korak petlje: " + i + ".

"); }

Budući da JavaScript interpreter očekuje primanje Booleove vrijednosti, svaka vrijednost rezultira Booleov tip, tada kada, kao rezultat sljedećeg smanjenja, varijabla i postane jednaka 0 (false), petlja će se zaustaviti.

Beskonačna for petlja

Da, da, znam da je ispravno pisati beskonačno :)

Dakle, petlja će biti beskrajna ako je uvjet uvijek istinit. Evo primjera:

Za (var i = 1; i

U ovom primjeru, varijabla i će se smanjiti i nikada neće postati veća od pet. Petlja će trajati zauvijek. Pokušajte pokrenuti ovu skriptu. Za mene se Chrome "izgubio u mislima" i nije ništa prikazao na ekranu, ali je nastavio razmišljati i razmišljati.

Budite oprezni kako biste izbjegli slučajno stvaranje beskonačnih petlji.

Prekid for petlje

Da biste prekinuli for petlju, baš kao i bilo koju drugu petlju, koristite naredbu break. Kada JavaScript mehanizam naiđe na naredbu break u tijelu petlje, prestaje izvršavati petlju i počinje izvršavati instrukcije skripte koje slijede petlju. ako ih ima.

U sljedećem primjeru zaustavit ćemo petlju u trećoj iteraciji (treći korak).

Za (var i = 1; i

Zakomplicirajmo malo primjer

Izvedimo samo 100 ponavljanja beskonačne petlje.

Var $counter = 1; za (var i = 1; i

Sljedeća iteracija: nastavak

Naredba za nastavak završava trenutnu iteraciju i započinje sljedeću.

Direktiva continue je "mlađa sestra" direktive break; ona zaustavlja samo ponavljanje, a ne cijelu petlju.

Za (var i = 1; i

Petlja u nastavku koristi nastavak za izlaz neparnih vrijednosti:

Za (var i = 0; i

Naravno, neparne vrijednosti mogu se ispisati pomoću petlje poput ove bez direktive za nastavak:

Za (var i = 0; i

Direktiva break/continue u "?"

Opišimo ukratko operator upitnika "?". Slično je if konstrukciji.

Logički dizajn:

If (uvjet) ( a(); ) else ( b(); )

Radi isto kao kod s operatorom "?".

Stanje? a() : b(); var i = 2; document.write("

1. dio.

"); if (i == 2) document.write("

Uvjet je funkcionirao.

"); else document.write("

Uvjet nije uspio.

");document.write("

2. dio.

"); i == 2 ? document.write("

Uvjet je funkcionirao.

") :document.write("

Uvjet nije uspio.

");

Tako, važno, ne možete koristiti prekid/nastavak desno od operatora "?"

U JavaScriptu je zabranjeno koristiti sintaktičke konstrukcije koje ne vraćaju vrijednosti u operatoru "?".

Donji primjer ne radi, sadrži grešku:

Za (var i = 0; i

Oznake za prekid / nastavak

Ponekad je potrebno stvoriti ugniježđene petlje. U takvom slučaju, dok se ugniježđena petlja izvodi, može biti potrebno zaustaviti roditeljsku petlju ili zaustaviti ponavljanje roditeljske petlje. Za to se koriste oznake.

Možete koristiti oznake za označavanje petlji, a zatim upotrijebiti break ili nastavak za izlazak iz petlje ili nastavak petlje novom iteracijom.

Markeri su jedini način da naredbe break i continue utječu na izvođenje vanjske petlje.

Instrukcija oznake koristi se samo u kombinaciji s break ili continue kako bi se osigurao alternativni izlaz iz petlje.

Oznaka ima sintaksu "ime:", naziv oznake mora biti jedinstven. Oznaka se postavlja ispred ciklusa, u istom retku ili s prijelomom retka.

Slično, možete koristiti break direktivu na ovom mjestu. Ali ako ga koristite, kao što razumijete, izvršenje ciklusa će prestati.

Var i, j; metka1: za (i = 0; i

JavaScript nema goto naredbu kao PHP; moguće je koristiti samo oznake break ili continue.

Oznake se rijetko koriste u JavaScript programiranju jer se smatra da čine kôd težim za čitanje i razumijevanje. Preporuča se korištenje funkcija prilikom kodiranja.

Ciklusi koriste se za izvršavanje određenog dijela koda nekoliko puta zaredom.

Zašto je to potrebno?- zamislite da trebate kvadrirati 100 elemenata niza. Ako pristupite svakom elementu zasebno po njegovom ključu, bit će potrebno 100 linija koda, a da biste napisali ovaj kod, trebat ćete potrošiti dosta vremena.

Ali to nije potrebno - imamo priliku da JavaScript izvede neke operacije umjesto nas potreban broj puta. Na primjer, kvadrirao sam sve elemente niza.

To se radi pomoću ciklusi.

while petlja

Ciklus dok izvršit će se do pravo(true) izraz koji mu je proslijeđen parametrom. Vidi sintaksu:

Dok (dok je izraz istinit) (izvršavamo ovaj kod ciklički; na početku svake petlje provjeravamo izraz u zagradama) /* Petlja će završiti kada izraz više nije istinit. Ako je u početku bio false, tada se nikada neće izvršiti! */

U osnovi ciklus dok može se izvesti beskrajno(ali to će uzrokovati zastoj skripte!), samo joj proslijedite izraz koji nikada neće postati lažna. Na primjer, ovako:

Ispisujmo redom brojeve od jedan do pet koristeći while petlju:

Var i = 0; //brojač petlje while (i< 5) { /* С помощью оператора ++ увеличиваем i на единицу при каждом проходе цикла. */ i++; alert(i); }

Obratite pažnju na varijablu ja- ona je tzv brojač ciklusa. Brojači se koriste za brojanje koliko je puta petlja izvršena. Osim toga, imaju i pomoćnu ulogu - u našem smo zadatku koristili brojač za prikaz brojeva od 1 do 5.

Uobičajeno je koristiti slova za brojače ja, j I k.

za petlju

Ciklus za je alternativa dok. Teže ga je razumjeti, ali ga se često više voli jer zauzima manje redaka.

For (početne naredbe; uvjet za završetak petlje; naredbe nakon petlje) (tijelo petlje)

Početne naredbe- to je ono što će se izvršiti prije početka petlje. Oni će biti izvršeni samo jednom. Obično se tamo postavljaju početne vrijednosti brojača, na primjer: i = 0.

Stanje kraja petlje - sve dok je istina, petlja će raditi, primjer: ja

Naredbe nakon petlje- ovo su naredbe koje će se izvršiti svaki put kada se završi petlja. Obično se tamo povećavaju brojači, na primjer: i++.

Upotrijebimo petlju za Ispisujmo redom brojeve od 0 do 9:

/* Na početku petlje, i će biti jednak nuli, petlja će se izvršavati dok i< 10, после каждого прохода к i прибавляется единица: */ for (var i = 0; i < 10; i++) { alert(i); //выведет 0, 1, 2... 9 }

Ciklus bez tijela

Možete izostaviti vitičaste zagrade u petljama - u ovom slučaju, petlja će izvršiti samo jedan redak ispod (ne preporučujem da to radite, često dovodi do pogrešaka):

Za (var i = 0; i< 10; i++) //<--- точки с запятой нет alert(i); //выведет 0, 1, 2... 9

Ali ako nakon ) stavite točku i zarez - petlja će se zatvoriti i sljedeći redak neće ići u nju, dobit ćete takozvanu petlju bez tijela, koja će se u našem slučaju jednostavno pomicati i kao rezultat promijeniti vrijednost varijable ja:

Za (var i = 0; i< 10; i++); //<--- точка с запятой есть alert(i); //выведет 9

Ova se petlja ponekad koristi; vidjet ćete primjere njezine upotrebe pri analizi problema u petlje.

Više naredbi u for petlji

Ako trebamo izvršiti nekoliko naredbi u zagradama, označavamo ih odvojene zarezima:

Za (var i = 0, j = 2; i

Pogledajmo gornju petlju: prije nego što petlja prođe, izvršit će se dvije naredbe: var i = 0, j = 2(imajte na umu da je var ovdje napisan jednom), a nakon svake iteracije - tri puta: i++, j++, i = i + j.

Ovaj primjer nije posebno koristan s programske točke gledišta; on jednostavno shematski pokazuje da se to može učiniti. Zapamtite to, bit će vam korisno u budućnosti.

for petlja za nizove

Korištenje petlje za Možete iterirati kroz elemente niza sekvencijalno. To se radi na sljedeći način:

<= arr.length-1; i++) { alert(arr[i]); //выведет 1, 2, 3, 4, 5 }

Ključna stvar je da ponavljamo od nule do duljine niza minus 1 (budući da je broj posljednjeg elementa niza za jedan manji od njegove duljine).

Ne morate oduzeti jedinicu, nego mjesto <= čini < :

Var arr = ; za (var i = 0; i< arr.length; i++) { alert(arr[i]); //выведет 1, 2, 3, 4, 5 }

for-in petlja

Za iteraciju kroz objekt koristi se takozvana petlja. za-u. Pogledajmo kako radi.

Neka nam je dan sljedeći objekt:

Var obj = (Kolja: 200, Vasja: 300, Petja: 400);

Izvadimo mu ključeve. Za to koristimo sljedeću konstrukciju: za (unesi obj), Gdje obj je objekt preko kojeg ponavljamo, i ključ- ovo je varijabla u koju će ključevi objekta biti sekvencijalno pohranjeni (njegov naziv može biti bilo koji koji vam padne na pamet - to je ono što će biti).

To jest, u ovoj petlji nema potrebe za navođenjem uvjeta završetka - ona će ponavljati ključeve objekta dok ne završe.

Dakle, ovako ćemo ispisati sve ključeve objekta (jedan po jedan):

Var obj = (Kolja: 200, Vasja: 300, Petja: 400); for (ključ u obj) ( alert(ključ); //prikazat će "Kolya", "Vasya", "Petya" )

Ako trebamo vrijednosti umjesto ključeva, moramo pristupiti našem objektu ključem, ovako: obj.

Kako radi: u varijabli ključ prvo će biti "Kolja", tj obj u ovom slučaju to nije važno obj["Kolja"], sljedeći put kada petlja prođe kroz varijablu ključ bit će "Vasya" i tako dalje.

Dakle, prikažimo sve elemente objekta:

Var obj = (Kolja: 200, Vasja: 300, Petja: 400); za (unesite obj) ( alert(obj); //prikazat će 200, 300, 400 )

instrukcija prekida

Ponekad moramo rano prekinuti petlju; u slučaju for petlje, to znači prije nego što petlja ponovi kroz sve elemente niza.

Zašto bi ovo moglo biti potrebno? Na primjer, suočeni smo sa zadatkom prikazivanja elemenata niza sve dok se ne naiđe na broj 3. Čim se naiđe na njega, petlja mora završiti svoj posao.

To se može učiniti pomoću uputa pauza- ako do njega dođe izvođenje petlje, petlja će prekinuti svoj rad.

Riješimo gornji problem - prekinimo petlju čim naiđemo na broj 3:

Var arr = ; za (var i = 0; i< arr.length; i++) { if (arr[i] === 3) { break; //выходим из цикла } else { alert(arr[i]); } }

Nastavite s uputama

Postoji i uputa nastaviti, nakon čega petlja započinje novu iteraciju. Ponekad može biti koristan za pojednostavljenje koda, iako se gotovo uvijek problem može riješiti i bez njega.

Što trebate učiniti sljedeće:

Počnite rješavati zadatke koristeći sljedeću poveznicu: zadaci za lekciju.

Kada sve odlučite, prijeđite na proučavanje nove teme.

Vrlo često je potrebno da se određeni dio programa izvrši više puta. Naravno, možete jednostavno učiniti ovo: kopirajte i zalijepite potreban broj puta. No, to je apsurdno, pogotovo ako se radnja mora izvesti npr. 1000 puta. Zato postoje tzv ciklusi, koji je prisutan u većini programskih jezika. I pričat ću vam o njima.

Sadrži određeni kod koji se pomiče više puta. Postoji nekoliko vrsta ciklusa: za, dok I učiniti dok.

Počnimo s prvim ciklusom (i najpopularnijim) - za petlju. Opći izgled ovog ciklusa je sljedeći:

Za (varijabla_iteracije = početna_vrijednost; uvjet; radnja_nakon_svake_iteracije) (
//programski kod
}

Da komentiram ovo što je ovdje napisano. prvi dolazi - varijabla ponavljanja. Ovo je normalno ime varijable za iteraciju. Sljedeće dolazi početna_vrijednost. Zapravo, naziv govori sam za sebe. Zatim dolazi uvjet, kada se ispuni (to jest, vraća se pravi) petlja se izvodi još jednom i na kraju radnja koja se izvršava nakon svake iteracije. Obično je to promjena varijable za iteraciju.

Napišimo jednostavnu skriptu koja će prikazati broj ponavljanja petlje:

Za (i = 0; i< 100; i++)
document.write(i + " ");

Ovdje smo postavili varijablu za iteraciju (zvanu ja), kojoj je dodijeljena vrijednost 0 . Zatim se provjerava uvjet: ja< 100 . Ako se izvrši, tada se izvršava jedna iteracija petlje. Nakon završetka svake iteracije, i++(odnosno povećanje varijable ja na 1 ). Uvjet se ponovno provjerava i ako je istinit, izvodi se još jedna iteracija. I tako do stanja ja< 100 neće postati lažna. Očito će biti netočna tek nakon 100 ponavljanja. Dakle, ova petlja će se izvršiti 100 puta, što možemo vidjeti ako pokrenemo ovu skriptu. I još jedna stvar. Budući da ovdje imamo samo jedan operator ( document.write()), tada prisutnost vitičastih zagrada nije obavezna. Ako imate 2 ili više operatora koji rade u petlji, morate ih instalirati.

Sada razgovarajmo o drugoj vrsti petlje u JavaScriptu - dok. U osnovi, ciklus je vrlo sličan za(iako su svi ciklusi slični). Ali ovdje je opći pogled drugačiji:

Dok (stanje) (
//programski kod
}

Kao što vidite, ne postoji varijabla za iteraciju, niti bilo kakve akcije nakon iteracije. Iz ovoga slijedi zaključak: da bi izašli iz petlje, potrebno je to učiniti u samoj petlji tako da " stanje" je postalo lažno. Ako se to ne učini, pojavit će se petlja i, posljedično, vaša skripta će stati.

Provedimo isti zadatak kao i prije, ali koristeći while petlja.

Var i = 0;
dok ja< 100) {
i++;
document.write(i + " ");
}

Prije pokretanja petlje stvorili smo varijablu ja, kojoj je dodijeljena početna vrijednost. Zatim se prije pokretanja petlje provjerava uvjet, te ako je istinit pokreće se iteracija petlje u kojoj inkrementiramo varijablu za iteraciju (u suprotnom dolazi do petlje). I prikazujemo ovu varijablu.

I na kraju posljednji pogled petlje u JavaScriptu - do-while petlja. Sintaksa je:

Čini(
//programski kod
) dok (uvjet)

Vrlo slično ciklusu dok, međutim, postoji samo jedna, ali vrlo temeljna razlika. Ako while petlja Prvo provjerava uvjet, a zatim izvršava iteraciju ili ne. Da do-while petlja prvo izvodi iteraciju, a tek onda provjerava uvjet. A ako je false, izlazi iz petlje. Drugim riječima, bez obzira na uvjet, zajamčeno je da će se ova petlja izvršiti barem jednom. Mislim da će ovaj kod biti suvišan, ali ipak.

Var i = 0;
čini(
i++;
document.write(i + " ");
) dok ja< 100)

Neću objašnjavati kod, siguran sam da ćete ga shvatiti bez mene. Stoga je bolje da prijeđem na dva zanimljiva operatora: pauza I nastaviti.

Počnimo s pauza. Ovaj vam operator omogućuje rano napuštanje petlje. Napišimo sljedeći kod:

Za (i = 0; i< 100; i++) {
if (i == 50) break;
document.write(i + " ");
}

Možete pokrenuti ovu skriptu i otkriti da samo brojevi do 49 , od kad i = 50 petlja je prekinuta, zahvaljujući operateru pauza.

Sada govorim o operateru nastaviti. Ovaj vam operator omogućuje prijelaz na sljedeću iteraciju petlje. Kako ovdje ne bismo previše opisivali, bolje je odmah pokazati primjer:

Za (i = 0; i< 100; i++) {
if (i == 50) nastavi;
document.write(i + " ");
}

Ako pokrenete ovu skriptu, vidjet ćete da broj nedostaje 50 . Ovo se dogodilo jer kada i = 50, prelazimo na sljedeću iteraciju petlje, prije koje ja povećava se za 1 i postaje jednaka 51.

To je, čini se, sve o čemu sam htjela pisati JavaScript petlje. Nadam se da vam je sve postalo jasno. Možete i sami smisliti problem i riješiti ga. Ovo će biti sjajna vježba.

Petlje su dizajnirane za izvršavanje istih instrukcija uvijek iznova.

U JavaScriptu postoje 4 vrste petlji:

  • For petlja. Ova se petlja koristi kada je poznat točan broj ponavljanja istih instrukcija.
  • Dok petlja. Dizajniran je za izvršavanje istih instrukcija sve dok je dani uvjet istinit.
  • Do...while petlja. Ova je petlja slična while petlji, ali se uvjet ne provjerava prije izvršavanja ponovljenih instrukcija, već nakon njih. Na ovaj način, za razliku od while petlje, čak i ako je uvjet inicijalno pogrešan, naredbe će se izvršiti barem jednom.
  • For...in petlja. Koristi se kada trebate iterirati kroz sva svojstva u objektu ili svaki element u nizu.

za petlju

Sintaksa petlje za:

Za (inicijalizacija; uvjet; konačni izraz) ( /* tijelo petlje */ )

  • inicijalizacija je izraz koji se izvršava jednom prije nego što se izvrši petlja; obično se koristi za pokretanje brojača;
  • uvjet je izraz čija se istinitost provjerava prije svake iteracije; ako je vrijednost izraza istinita, izvodi se iteracija, u suprotnom for petlja izlazi;
  • konačni izraz je izraz koji se izvršava na kraju svake iteracije; obično se koristi za promjenu brojača;
  • tijelo petlje - upute koje je potrebno ponoviti.

Pogledajmo primjer petlje koja će na konzolu ispisivati ​​brojeve od 1 do 9:

Var i; // Petlja za od 1 do 9, u koracima od 1 za (i = 1; i<= 9; i++) { console.log(i); }

U ovom primjeru:

  • inicijalizacija: i = 1 (dodjeljivanje varijabli i vrijednosti 1);
  • uvjet završetka petlje: ja<= 9 (значение переменной i не меньше 9);
  • izraz koji će se izvršiti na kraju svake iteracije: i++ (povećati vrijednost varijable i za 1);
  • upute koje treba slijediti: console.log(i) (ispis vrijednosti brojača na konzolu).

Neobavezni dijelovi for petlje

U formi, inicijalizacijski blok je neobavezan.

Var i = 1; // Petlja za za (; i<= 9; i++) { console.log(i); }

Blok uvjeta u for petlji također nije obavezan. Bez uvjeta, petlja će se izvršiti beskonačan broj puta. U ovom slučaju, da biste ga prekinuli (izašli iz petlje), morate koristiti naredbu break.

Var i; // Petlja for for (i = 1; ; i++) ( if (i > 9) ( // uvjet za prekid prekida petlje; ) console.log(i); )

Finale za izraz također nije obavezno. U ovom slučaju, brojač petlje može se, na primjer, promijeniti u tijelu.

Var i; // For petlja for (i = 1; i<= 9 ;) { console.log(i); i++; }

Možete izostaviti ukupno 3 izraza:

Var i = 1; // Petlja for for (; ;) ( if (i > 9) ( break; ) console.log(i); i++; )

Možete koristiti prazan izraz (;) kao tijelo for petlje.

Na primjer:

Var arrA = , arrB = ; za (i = 0; i< arrA.length; arrB[i] = arrA / 2) ; console.log(arrB); //

Primjeri korištenja za

Upotreba for petlje za ponavljanje kroz elemente niza:

Var arr = , // niz i = 0, // brojač lenArr = arr.length; // duljina niza za (i; i< lenArr; i++) { console.log(arr[i]); }

Prekini i nastavi upute

Osim toga, posebne upute za prekid i nastavak mogu se koristiti unutar tijela petlji.

Naredba break namijenjena je za prekid izvođenja petlje. Oni. izlazi iz trenutne petlje i prenosi kontrolu na instrukciju koja ga slijedi.

Naredba continue prekida trenutnu iteraciju petlje i prelazi na sljedeću.

Primjer u kojem ćemo na konzolu ispisati neparne brojeve od 1 do 11:

Var i; for (i = 1; i <= 11; i++) ( // ako je broj u varijabli i paran, prijeđite na sljedeću iteraciju if (i %2 === 0) ( nastavi; ) // ispišite vrijednost varijable i na konzolu console.log(i); ) // 1, 3, 5, 7, 9, 11

Petlja s preduvjetom while

Dok petlja izvršava iste naredbe (tijelo petlje) sve dok neki uvjet nije istinit. Istinitost uvjeta provjerava se prije svakog izvođenja tijela petlje. Ako je uvjet lažan prije prve iteracije, tada se petlja nikada ne izvršava.

// deklariranje varijable a i dodjeljivanje vrijednosti 0 var a=0; //while petlja s uvjetom a

Petlja s postuvjetom do...while

Do...while petlja, kao i while petlja, izvršava iste naredbe (tijelo petlje) dok neki uvjet nije istinit. Ali za razliku od while petlje, u do...while petlji uvjet se provjerava nakon svakog izvođenja tijela petlje. Čak i ako je uvjet inicijalno pogrešan, tijelo petlje će se ipak jednom izvršiti (budući da se uvjet provjerava nakon što se tijelo petlje izvrši).

// deklariranje varijable a i dodjeljivanje vrijednosti 0 var a=0; //do...while petlja s uvjetom a

Kao što je gore navedeno, for...in petlja se koristi za ponavljanje kroz elemente polja i svojstva objekta. U ovoj lekciji samo ćemo pogledati opću sintaksu for...in petlje, ali ćemo je detaljnije upoznati u sljedećim lekcijama.

Način na koji for...in petlja radi je da varijabla x preuzima sva imena svojstava objekta y ili indekse niza y. Stoga vam je u svakoj iteraciji dostupno svojstvo objekta ili element niza.