Асаліны цыклаў у TypeScript: while, do-while, for, break і continue
Дазвольце дазнацься, як цыклы while, do-while і for у TypeScript ацэнююць свае умовы, чаму змена дыямэнту зменны ў цыкле паўтарае рэзультаты, і як ключавыя словы break і continue зменяюць тэкстуру виконання коду.
Крыніцы: Mastering Loops in TypeScript: while, do-while, for, break & continue
Ціклы дазваляюць запускаць той самы блак ад коду парадозна, калі выплывае паводлівасць, замест таго каб перакладаць адзін за адным выказванні. Яны здаюцца простымі, але большасць бягоў у ціклах вынікае з трох пунктав: калі перакладваецца паводлівасць, дзе знаходзіцца зменная цікла і дзе ў тэле цікла распаложыцца break або continue. У гідзе прадстаўлены ціклы TypeScript while, do-while і for з малымі прыкладамі, выход якіх можна спакульгаваць па лініях, тады вы зможаце чытаць і пісаць код для ітерацый без неспадзянак.
Чаму ітерацыя кращая за парадоз
Для выведзення цифр з 1 да 10 без цікла патрабуецца дзесяць вызоваў console.log. З ціклам вы описваеце задачу адназначна, а система яе парадозна, і размах коду застаецца тым жа, незалежна ад таго, чырэз дзесяць чы ў дзесяць тысяч разоў трэба яго запускаць.
Цікл while: спачатку перакладванне, потым запуск
Цыкл while мае найпростейшую структуру з усіх:
while (condition) {
// statements
}
Умова ацэнаваная до кожнага проходжэння цыклу. Калі яна true, выпаняецца тэла цыклу; калі становіцца false, цыкл завершаецца. Для правяльнага while-циклу патрэбны тры элементы:
- пачатковая значэнне для зменнай, ад кой караецца умова;
- сама умова;
- элемент у тэле цыклу, який спрыяе таму, каб умова стала
false.
Якщо прыняць трэці элемент, цыкл ніколі не завершыцца, што ўзьятае пад увагу нижэй.
Працаванне ад 1 да 10
Тут видны всі тры элементы: i пачынаецца з 1, цыкл працюе, паколькі i <= 10, а i++ паднімае його значэнне пасля кожнага проходжэння:
let i: number = 1; // initialization
while (i <= 10) {
console.log(i);
i++;
}
Фільтрацыя чэснага лічб
Ёнколі хочаце выдрукуваць толькі чысла з парных числаў у гэтым дзіапазоне, трэба продовжваць пераглядаць кожную значэнне, але дадаць перакананне ў самым кодзе. Аператар модуля % вяртае залишок ад дзелення, таму i % 2 == 0 ўсё правда тады, калі i яе парнае:
let i: number = 1;
while (i <= 10) {
if (i % 2 == 0) {
console.log(i);
}
i++;
}
Існуе простыяй спосаб разлічвання да падобнага рэзультата: не трэба выканання пераканання ўзагалі, а трэба кожны раз прыбавляць 2. Заўважыце, што гэты варіянт пачынаецца з 0, таму ў яго выходзе таксама будзе 0:
let i: number = 0;
while (i <= 10) {
console.log(i);
i = i + 2;
}
Выход: 0, 2, 4, 6, 8, 10
Фільтраўанне нечыслаў
Якша змяніць умову на != 0, тады будуць выбраны нечыслаў. Пачатак з 0 тут нешкодны, таму што 0 яе парнае і ёй будзе фільтраванаць:
let i: number = 0;
while (i <= 10) {
if (i % 2 != 0) {
console.log(i);
}
i++;
}
Выход: 1, 3, 5, 7, 9
У гэтых прыкладах выкарыстоўваюцца == і !; строгія формы === і !== зазвычай ўжываюцца, таму што яны ніколі не ператвараюць типы, хоця для двух числаў рэзультат застаецца ідэнтычным.
Абліквач
Ёсць калькуляваць у спад, трэба пачаць з вялікага значэння і зменшваць яго, пакуль яго значэнне будзе прынямнае, тое ўсё 1:
let i: number = 10;
while (i >= 1) {
console.log(i);
i--;
}
Бесканечныя цыклы і прычыны ўтварэння іх
Умова while — гэта проста выраз, які дае булева значэння, таму while (true) ўсё абсалютна дазволены. Цыкл нижчэй будзе выдаваць данні вечна, таму што нічога не можа яго завершыць:
let i: number = 1;
while (true) {
console.log(i);
i++;
// no break, no exit condition this runs forever
}
Часта прычына бесканцэнтных цыклаў — адпаведная зменная ніколі не абнавляецца чы працюе неправильна. Такі цыкл блакуе ўсё іншае на сваймай гілцы, таму вікна браузера чы процесы Node.js здаюцца застойванымі. Намерны while (true) ўсё ж дапускаецца, якщо ён супакоўваецца за дапамогою чыстае выходу, зазвычай break (пераказана нижэй), напрыклад у логіцы «прабаваць па-новай, пакуль не будзе успеху».
Цыкл do-while: выконваецца адной раз, потым пераказваецца
У цыкле do-while умова пераказваецца толькі ў канцы:
do {
// statements
} while (condition);
Паколькі пераказваўце выконванняяецца пасля тэлы, тэла завжды выконваецца прынеймна адной раз, незалежна ад таго, якая ўмова. На протыяжэнні, звычны while можа не выконвацца жаданы раз.
Калі умова спачатку ў значэнні true, do-while паводзіцца так сама, як і while:
let i: number = 1;
do {
console.log(i);
i++;
} while (i <= 5);
Разлік стае пометным, калі умова з самага пачатку ў спрэчы:
let i: number = 10;
do {
console.log(i);
i++;
} while (i <= 5);
Расход: 10
Корпус ціклу выконваецца без умов, выдрукуючы 10 і паднімаючы i да 11. Лявае тады выконвуецца i <= 5; яго рэзультат — false, таму цікл завершаецца пасля аднай ітерацыі. Цікл while (i <= 5), які пачынаецца з 10, нічога не выдрукуе. Выкорыстоўваюце do-while, калі неабходна прынеймней адна першая ітерацыя, напрыклад, каб хоць раз паказаць запит.
Цікл for: усё ў аднай заголовцы
Цікл for — гэты той, які вы будете викорыстоўваць найчащэй, особліва калі заздалегідь ведаеце, сколькі разоў трэба павтарыць або на сколькі должна змяніцца лічылка. Ён аб’еднвае ініцыялізацыю, умову і апдэйт у адну заголовцы, што робіць яго болей компактным чым адпаведны while:
for (initialization; condition; increment/decrement) {
// statements
}
Порядак, у якому выконваюцца этыя часты, варта запам’ятаваць:
- Ініцыялізацыя выконваецца адна раз, перш чым працюе ўсё інше (на прыклад
let i = 1). - Оцэнюецца умова. Якщо яна
true, выконваецца тэла циклу; якщоfalse, цикл завершаецца. - Пасля тэла выконваецца выраз для апдэйта (на прыклад
i++). - Контроль вяртаецца да пункту 2, і цикл павтараецца, пакуль умова не стане
false.
Іншымі словамі, ініцыялізацыя выконваецца толькі адна раз, тады як умова і апдэйт выконваюцца ў кожны цикл.
Праляганне ад 1 да 10
for (let i = 1; i <= 10; i++) {
console.log(i);
}
Два спосабы отрымання чэтных чисоў
Як і у while, можна пралягаць па два елементы:
for (let i = 2; i <= 10; i += 2) {
console.log(i);
}
альбо пераглядаць кожную значэнне і фільтруваць яе ў тэле циклу:
for (let i = 2; i <= 10; i++) {
if (i % 2 == 0) {
console.log(i);
}
}
Оба спосабы выдрукваюць тую ж самую последовальнасць:
2
4
6
8
10
Метод «Stepping» выкарыстоўвае меншае количество операцый, таму што ён пераглядае толькі чэсныя значэння; фільтрацыя є болей гнучкай, калі правіла не являюцца фіксаваным крокам, напрыклад «дзелімы на 3 або 7».
Скарчванне
Апдэйт зі зменшэнням значэння запускае цыкл у зворачным напрамку:
for (let i = 10; i >= 1; i--) {
console.log(i);
}
Рэзультат: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
Чаму зменная цыклу становіцца 6 пасля завершэння цыклу
Месца, дзе вы працэўваеце зменную цыклу, вялічыць тое, што застаноўся пасля ёй. У гэтым прыкладзе i працэўваецца перад цыклам, а блок for толькі прызначае ёй значэння:
let i: number;
for (i = 1; i <= 5; i++) {
console.log(i);
}
console.log(i);
Рэзультат: 1, 2, 3, 4, 5, 6
Паколькі i знаходзіцца ў зовнішнем прыметку, выкананне console.log(i) у канцы все ж такі можа даўжыну яго значэння, якое засталося пасля ціклу. Гэта 6, а не 5, з-за прабегу аперацый: пад час последнага пройшчы i равнае 5, код выведае яго, а пасля актуалізацыі його значэнне становіцца 6, і толькі тады умова 6 <= 5 не выпалюеся і цікл завершаецца.
Больш распашчытаны стыль, for (let i = 1; i <= 5; i++), стварае прыметку i у блакучым прыметку, якая дзейсніца толькі пад час ціклу, таму пасля яго ёй вяршыцца. Апіл да яе пасля ціклу ў TypeScript вызывае памылку часу компілявання (“Cannot find name 'i'”), а ў звычным JavaScript вызываецца ReferenceError часу выканання. Яшчэ краща яе задаць у заголовку; вярхнюе заданне трэба выкарыстоўваць толькі тады, калі патрэбна фінальная значэнне.
Змена прабегу ціклу за дапамой break і continue
Две заповедзі ўскоку дазваюць змяніць нормальны ход цыклу заўтрачэння ў яго тэле:
breakнегайна завершае цыкл, незалежна ад таго, сколькі ітерацый засталаеся.continueпрыпіняе толькі текущую ітерацыю і пераходзіць да наступной; цыкл продовжвае працаваць.
У цыкле for заповедзь continue все равно выконвае выраз апдэйта прытым, як прабуецца зноў пераканацца у выпалоўваючай умове, таму лічылка продовжвае растаць.
break: важна пазіцыя ў тэле
Ёсць прыклад, калі перакананне break выконваецца раней за выведэнне:
let i: number;
for (i = 1; i <= 10; i++) {
if (i == 5) {
break;
}
console.log(i);
}
Раслідаванне: 1, 2, 3, 4
Калі i досягае 5, цыкл завершваецца раней, чым console.log мае можлівасць выконацца, таму 5 ніколі не праказваецца.
Якшчы перасунуць выведэнне раней за перакананне, рысунок змініцца:
let i: number;
for (i = 1; i <= 10; i++) {
console.log(i);
if (i == 5) {
break;
}
}
Рэзультат: 1, 2, 3, 4, 5
Условіе застаўляецца незменным, пры тым 5 тепер апісваецца, таму што вывод практыкуецца раней за пераконтроўкай. Каля break і continue аднойчы, порядак запаведзей у тэле вяліканае значэнне для рэзультата.
continue: прыпусканне адной значэння
Замена break на continue ператварае "зупінка на 5" у "прыпусканне 5">:
let i: number;
for (i = 1; i <= 10; i++) {
if (i == 5) {
continue;
}
console.log(i);
}
Рэзультат: 1, 2, 3, 4, 6, 7, 8, 9, 10
Цикл продовжваецца; ён проста не выводзіць даныя для той адной ітерацыі.
Прыпусканне кожнага нечыёвага числа
У поўнанні з фільтрам, continue направляе кожная нечыёвае значэнне безпосередзьва да наступной ітерацыі:
let i: number;
for (i = 0; i <= 10; i++) {
if (i % 2 != 0) {
continue;
}
console.log(i);
}
Рэзультат: 0, 2, 4, 6, 8, 10
Прыпусканне спецыяльных значэнняў з ліста
Умова можа быць настолькі складной, насколькі вы хачаце. За дапамою логічнага аператара OR || гэты цыкл прыходзіць за 3, 5 і 7:
let i: number;
for (i = 0; i <= 10; i++) {
if (i == 3 || i == 5 || i == 7) {
continue;
}
console.log(i);
}
Рэзультат: 0, 1, 2, 4, 6, 8, 9, 10
Для дыявольскай лісты прыхоўдзеньня [3, 5, 7].includes(i) або Set ўжываюцца лепей.
Ключовыя моманты
whileпераказвае сваяю умову пры кожным цікле і можа не выконвацца ні разу;do-whileпераказвае яе пасля і завжды выконваецца прынеймна раз.- Кожны цыкл патрэбуе апдэйта, який зрэшты зробіць умову няправдзівай; інакш будзе бесканцовы цыкл, який заблокуе адэнт.
- У цыкле
forініцыялізацыя выконваецца адна раз, тады як умова і апдэйт — пры кожным цікле, таму лічыльнік заканчваецца на адны крок пасля ліміту.
let у пачатку ціклу дзеўае яму межы ціклу; акларацыя яго за межамі ціклу дазволяе яго заканчоўнай значэнню застацца.break завершае цікл, а continue прыпускае адна ітерацыя; месца ўстановкі гэтых каманд у адносе да іншых запаведзей вплывае на рэзультат.Умовныя операторы выбіраюць, калі выконваецца код; ціклы выбіраюць, як часта. Яе разам вони пакрываюць большую частку потока керавання, які вы будете пісаць.