# Вложенные декларативные структуры и код в них. Отображение циклических и древовидных структур. Циклы. ## 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
Enter a data please:
``` > Сформируйте структуру данных **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