# Занятие 3. Циклы и массивы.

## Отладка

**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` в коде.

### Пошаговая отладка и консоль.

Очень удобно использовать консоль и пошаговую отладку одновременно. Консоль предоставляет все переменные и их текущие значения, которые сейчас есть в
отлаживаемом коде, таким образом вы можете поэкспериментировать с этими значениями и, например, запустить из консоли следующий проблемный оператор в коде
или его часть для нахождения логической ошибки.

### Задание 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 после цикла?

#### Задание
Напишите аналогичный цикл `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. Например строка (`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]
```

#### Задание
Перепишите последнюю строку примера так, что бы можно было сконкатенировать массив с любым количеством элементов.

### Присвоение, сравнение, копирование массивов и различия со строками.

В отличие от всех тех типов, которые вы видели ранее, массивы ведут себя как полноценные *объекты*. Это значит, что при присвоении переменных, содержащих
массив, создание нового массива **не** происходит, и переменная ссылается на тот же массив:

```javascript
a = b = [1,2,3]
//[1, 2, 3]
a == b
//true
a[0] = 500
//500
a
//[500, 2, 3]
b
//[500, 2, 3]
```

Для создания копии массива (чего обычно ожидают от присвоения), существует метод `slice`:
```javascript
a = b.slice()
//[500, 2, 3]
a
//[500, 2, 3]
a[0] = 1
//1
b
//[500, 2, 3]
a
//[1, 2, 3]
a == b
//false
```

Однако копия не равна оригиналу несмотря на одинаковое содержимое:
```javascript
a
//[1, 2, 3]
b
//[500, 2, 3]
b[0] = 1
//1
b
//[1, 2, 3]
a == b
//false
```

Пустой массив равен false:
```javascript
[] == false
//true
!![]
//true эта проверка не работает для объектов, кроме null
false == []
//true
[] == []
//false ведь это два разных массива
```


### Практикум по методам класса Array