# Занятие 3. Циклы и массивы. ## Отладка **Браузер** на обычном компьютере или ноутбуке содержит в себе средства отладки вида страницы (**HTML**/**CSS**) и сопутствующего **JS**-кода. Эти средства называются **Developer Tools** и вызываются по **F12** **Ctrl-Shift-I** или Правая Кнопка->Посмотреть код элемента на странице. **Developer Tools** содержит в себе множество средств отладки кода. Для хорошего понимания управляющих конструкций (**условий** и **циклов**) полезно разобраться с **пошаговой отладкой** - выполнением кода по шагам. Это позволяет увидеть, какие блоки кода выполняются или не выполняются в условных операторах и каковы значения переменных в каждый момент времени выполнения кода. Для начала пошаговой отладки устанавливается **точка останова** - строка кода, с которой обычный режим выполнения прерывается и начинается отладка по шагам. В **Developer Tools** найдите вкладку *Source*, в ней свой файл c кодом, и кликните на номере нужной строки слева от текста кода. Если вы используете [repl.it](http://repl.it), другие **онлайн-IDE** или **console**, то у вас будут определенные сложности с нахождением вашего кода и строки в нём. Поэтому вы можете вставить ключевое слово `debugger` в ваш код - это работает так же, как **точка останова** на строке в Developer Tools. ### Отладка по шагам. **Пошаговая отладка** позволяет детально заглянуть в процесс выполнения вашего кода - вы можете узнать всё ли работает так, как нужно, в любой строке и таким образом упростить поиск логических ошибок в коде. Основные операции: - **Step over next function call** (**F10**) - следующий шаг/оператор в вашем коде. После выполнения каждой команды вы можете ознакомится со значениями переменных, наведя на них курсор мыши, написав их в консоли, или же используя вкладку Watch - **Resume script execution** (**F8**) - переход из режима отладки по шагам в обычный режим выполнения кода. Таким способом вы пропускаете хорошо отлаженные части кода. Этот режим может быть прерван следующей **точкой останова** или ключевым словом `debugger` в коде. ### Пошаговая отладка и консоль. Очень удобно использовать консоль и пошаговую отладку одновременно. Консоль предоставляет все переменные и их текущие значения, которые сейчас есть в отлаживаемом коде, таким образом вы можете поэкспериментировать с этими значениями и, например, запустить из консоли следующий проблемный оператор в коде или его часть для нахождения логической ошибки. ### Отладочный вывод Вы всегда можете добавить `console.log` в место, где хотите получить информацию о состоянии программы. Этот способ хорош как дополнение к остальным. Так же вы можете написать определенное условие для отладки, вставить в него `console.log` и поставить **точку останова**. ### Комментирование как инструмент отладки В любой момент вы можете выключить ту или иную часть кода, не стирая её с помощью **синтаксиса комментариев**. ```javascript var a = b + 5; //a += prompt(); //однострочный комментарий, временно "выключаем" ввод пользователя. //console.log(a); //выключенный отладочный вывод, что бы не мозолил глаза, пока не нужен var c = somePerfectFunction(a) //функция работает хорошо /* if (blahala){ asdfasdf explodeMoon() */ //многострочный комментарий с большим куском кода, выключен потому что в нём куча ошибок. ``` ### Задание 1 Поиграться с вашим ДЗ, добавив туда точки останова, и посмотреть, чему равны переменные и как ведут себя `if` и `switch` в зависимости от значения переменных. Отладьте задание о логине и пароле в ДЗ. ## Циклы. **Цикл** - последовательность операторов, которая повторяется. **Цикл** состоит из: - тела цикла, т. е. блока кода, который повторяется, - условия, которое проверяется перед очередным повтором цикла. Однократное выполнение тела цикла называется **итерацией**. ### Ключевые слова `break` и `continue`. Эти ключевые слова применяются в теле и позволяют изменять логику работы цикла: - `break` обрывает выполнение цикла в любом месте тела - программа продолжается после цикла; - `continue` обрывает выполнение текущей *итерации* и начинает следующую итерацию. ### Цикл `while` Цикл `while` выполняется, пока условие истинно и прекращает свое выполнение как только условие становится ложно: ```javascript var password = ''; var rightPassword = 'qwerty'; while (password != rightPassword){ //Пока пароль не равен верному... password = prompt('Введите пароль:', ''); //спрашивать пароль } //возвращаемся на while (....) ``` Цикл `while` в некотором смысле схож с `if` - тело выполняется если условие верно; однако `if` выполняет тело однократно, а `while` выполняет тело *пока* условие верно. #### `break` ```javascript var password = ''; var rightPassword = 'qwerty'; while (password != rightPassword){ //Пока пароль не равен верному... password = prompt('Введите пароль:', ''); //спрашивать пароль if (password == null){ //пользователь нажал отмену... break; //прерываем цикл } } ``` #### `continue` ```javascript var user = ''; var rightUser = 'admin'; var password = ''; var rightPassword = 'qwerty'; while (user != rightUser || password != rightPassword){ //Пока пользователь не равен верному или пароль не равен верному... user = prompt('Введите имя пользователя:', ''); //спрашивать пользователя if (user != rightUser){ //нет смысла спрашивать пароль, если пользователь неверный, поэтому... continue; //новая итерация. } password = prompt('Введите пароль:', ''); //спрашивать пароль } ``` ### Цикл `do ... while` Этот цикл называется циклом с *постусловием*, то есть проверка условия выхода из цикла происходит не *перед* а *после* выполнения тела цикла. Таким образом, цикл с *постусловием* выполняется **хотя бы один раз**. Для нашего примера этот цикл подходит лучше, чем обычный `while`. Почему? ```javascript var password = ''; var rightPassword = 'qwerty'; do{ password = prompt('Введите пароль:', ''); //спрашивать пароль }while (password != rightPassword) //Пока пароль не равен верному... ``` ### Цикл `for` Это самый сложный и мощный цикл, в синтаксисе заголовка которого, кроме условия, присутствуют еще и другие операции: - инициализация, т. е. то, что делается перед началом цикла - условие продолжения (как в `while`) - операции, которые выполняются после каждой итерации В общем виде цикл `for` выглядит так: ```javascript for (init1,init2,...;condition;iter1,iter2...){ .... } ``` Где: - `initN` - это те или иные инициализирующие операторы, которые выполняются *перед* началом выполнения цикла - `condition` - условие продолжения - `iterN` - операции, выполняющиеся после какждой *итерации* ```javascript for (var i=0;i<10;i++){ console.log(i); } ``` Этот цикл считает от 0 до 9, каждую итерацию выводя значения i в консоль. **Вопрос**: чему будет равен i после цикла? ```javascript var letters = "abcdefghij"; for (var i=0;i<10;i++){ console.log(i + ":" + letters[i]); } ``` Обратите внимание на работу со строкой как с массивом. #### Задание Напишите аналогичный цикл `while` ```javascript for (var i=10,str="";i>0;i--,str+="#"){ console.log(i, str); } ``` **Вопрос**: чему будет равен i и str после цикла? #### Задание Напишите аналогичный цикл `while` Таким образом становится ясно, что `for` - не более чем сокращенная форма `while`, или, другими словами, *синтаксический сахар*. ### Вложенные циклы **Циклы** могут быть *вложенными*, т. е. исполняться один внутри другого. В таком случае на **каждую** *итерацию* внешнего цикла приходятся *все* *итерации* вложенного. Такие циклы часто употребляются для работы с дву- и более мерными данными или отображениями (таблицы, картинки, массивы и так далее) Например: ```javascript var i = 'a'; var str = ""; for (j=0;j<10;j++){ str += i; } console.log(str); ``` Таким образом мы можем создать строку любой длины с любым символом. А теперь оборачиваем этот цикл внешним: ```javascript for (var i=0;i<10;i++){ var str = ""; for (j=0;j<10;j++){ str += i; } console.log(str); } ``` #### Задание Напишите вложенный цикл, который будет создавать HTML для таблицы умножения. Используйте тэги `table`, `tr`, `td`. Таблица должна создаваться в строковой переменной. Для вывода этой переменной используйте `document.write`. Пример: | 0 | 1 | 2 | | --- | --- | --- | | 1 | 1 | 2 | | 2 | 2 | 4 | Таблица выше создается с помощью следующего синтаксиса **HTML**. Для проверки вы просто можете скопировать этот HTML в какой-то файл .html и пробовать открыть его в браузере. Или же присвоить его какой-то строковой переменной (`str`) и попробовать вывести в окно браузера: `document.write(str)`. Так же можно попробовать его в repl.it или jsfiddle. ```HTML
0 1 2
1 1 2
2 2 4
``` То есть, таблица начинается с тэга `` и заканчивается парным тэгом `
`. Каждая строка начинается с тэга `` и заканчивается парным закрывающим тэгом ``. Каждая ячейка в строке начинается тэгом `` и заканчивается парным закрывающим тэгом ``. Между парой тэгов `` и `` находится текст, который отображается в ячейке. Используя вложенные циклы и строковую конкатенацию (`str += "то, что надо добавить к строке"`) сделайте код, который генерирует таблицу умножения. Для вывода таблицы используйте `document.write(str)`. ## Массивы **Массив** - это упорядоченная структура данных, состоящая из нумерованных ячеек. Нумерация идет от 0. Например строка (`String`) - массив символов. Доступ к ячейкам массива происходит по её номеру в квадратных скобках: ```javascript var myName = "asmer" myName[0] myName[4] myName.length ``` Для оперирования с массивами зачастую используются циклы. #### Задание Выведите какую-либо строку побуквенно, используя цикл `for`. Длина массива или строки находится в свойстве `length`. ### Определение массива Массивы можно определять несколькими способами ```javascript var oopWay = new Array(1,2,3); var inlineWay = ["some", "other", "array'"]; ``` ### Операции с элементами массива В общем те же самые, что и с обычными переменными. Просто не забудьте добавить квадратные скобки и индекс (номер элемента): ```javascript var oopWay = new Array(1,2,3); var inlineWay = ["some", "other", "array'"]; oopWay[0]++ oopWay[2] = oopWay[0] - oopWay[1] inlineWay[3] = inlineWay[0] + inlineWay[1] + inlineWay[2] ``` Для обхода всего массива используйте цикл `for`: ```javascript for (var i=0;i