# Вложенные декларативные структуры и код в них. Отображение циклических и древовидных структур. Циклы.

## HTML

**HTML** - древовидная структура данных. Сегодня мы научимся оперировать схожими структурами в **JS**.

## Array

Вы уже знакомы с массивами. Декларативно массивы создаются с помощью `[]`. Каждый элемент массива отделен от соседнего с помощью запятой (`,`):
```javascript
var arr1 = [0,1,2];
var arr2 = ["какие-то","плохие", "слова"];
var arr3 = [[0,1,2], [0,2,4], [0,3,6]]; 
```
`[]` - это выражение, которое вычисляется в значения типа "массив".

В качестве элемента массива может быть значение любого типа данных **JS**.

> Какие можно сделать выводы, исходя из последнего выражения. Что именно можно писать в коде в качестве элементов массива?

## Object

Как и массивы, объекты можно создавать декларативно:
```javascript
var notebook = {
    brand: "HP",
    type:  "440 G4",
    model: "Y7Z75EA",
    ram: 4,
    size: "14",
    weight: 1.8,
    resolution: {
        width: 1920,
        height: 1080
    },
};

var phone = {
    brand: "meizu",
    model: "m2",
    ram: 2,
    color: "black",
};

var person = {
    name: "Donald",
    surname: "Trump"
}
```

В качестве ключа в объектах используется строка, или значение, приведенное к строке. В качестве значения, как и в массиве - любое значение любого типа данных **JS**

> Какие можно сделать выводы, исходя из последнего выражения. Что именно можно писать в коде в качестве элементов объекта?

## Древовидные структуры данных.

Как видно в примере выше, объект или массив может в качестве элемента иметь значение любого типа данных, в том числе другой объект или массив. Всё вместе это организовывает структуру данных, схожую с **HTML**, однако в другом синтаксисе:

```html
    <body>
        <div>
            <span>Enter a data please:</span><br/>
            <input type='text' id='name'>
            <input type='text' id='surname'>
        </div>
        <div>
            <button id='ok'>OK</button>
            <button id='cancel'>Cancel</button>
        </div>
    </body>
```
> Сформируйте структуру данных **JS**, которая содержит информацию о **HTML** выше.

> Создайте объект, используя `prompt` и `confirm` для значений тех или иных полей.

## Структуры данных, присвоение, ссылки и значения

Объекты и массивы при присвоении **не** копируются. Просто другая переменная связывается с *тем же* значением, что первая:

```javascript
var a = [5],b;
b = a;
b[0] *=2;

alert(b[0] != a[0] ? "b - не a" : "b - это a");
```

```javascript
var a = 5,b;
b = a;
b *=2;
alert(b != a ? "b - не a" : "b - это a");
```

В определенных ситуациях (обычно когда вы хотите что-то поменять в объекте, но хотите сохранить "оригинальный" объект) это мешает. Но, с другой стороны, это позволяет делать циклические ссылки в объектах.

> Укажите у человека его гаджеты в отдельных полях. Задайте гаджетам владельца. Как это сделать?

> Можно ли задать циклические ссылки при декларативном описании массивов или объектов?

> Сделайте объект или массив с единственным элементом со ссылкой на самого себя.

## Императивный подход к созданию сложных структур данных

### Массивы.

Как уже было показано, вы можете задавать значение для элементов массива через присвоение с использованием индекса:

```javascript
var arr = [];
arr[0] = 5;
arr[1] = 10;
arr[2] = 15;
```

Обратите внимание, что индекс в `[]` является **выражением**, то есть вы вольны в использовании любых переменных, математических операций, функций и всего того, что можно использовать в выражениях.

### Объекты

Объекты схожи с массивами, только в качестве индекса используется строка, а не положительное целочисленное значение

```javascript
var arr = {};
arr["first"] = 5;
arr["second"] = 10;
arr["third"] = 15;
```

Или так:

```javascript
var arr = {};
arr.first  = 5;
arr.second = 10;
arr.third  = 15;
```
однако в последнем случае вы не можете использовать выражения в качестве ключей.

> Сделайте добавление нескольких элементов массива императивно, занося в массив значения, полученные с помощью `prompt`

> Сделайте добавление нескольких элементов массива императивно с помощью **синтаксически одинакового кода** для каждого элемента.


## Циклы.

**Цикл** - последовательность операторов, которая повторяется.

**Цикл** состоит из: 
- тела цикла, т. е. блока кода, который повторяется, 
- условия, которое проверяется перед очередным повтором цикла.

Однократное выполнение тела цикла называется **итерацией**.

### Ключевые слова `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]
```

Для обхода всего массива используйте цикл `for`:
```javascript
for (var i=0;i<arr.length;i++){
    //какие-то операции с arr[i]
    console.log(arr[i])
}
```

#### Задание
Перепишите 
```javascript
inlineWay[3] = inlineWay[0] + inlineWay[1] + inlineWay[2]
```
так, что бы можно было сконкатенировать массив с любым количеством элементов, используя цикл `for`.