|
@@ -0,0 +1,193 @@
|
|
|
+# Ассоциативные массивы, `in`, JSON
|
|
|
+
|
|
|
+Кроме обычных массивов, в которых ключем служит целое число от 0 до `array.length -1`, существуют **ассоциативные массивы**, ключем в котором может быть любой другой
|
|
|
+тип данных, который **JS** приводит к строке. В **JavaScript** нет специального типа данных для ассоциативных массивов - вместо этого ассоциативные
|
|
|
+массивы представлены объектами (`Object`):
|
|
|
+
|
|
|
+
|
|
|
+## Создание ассоциативного массива и доступ к полям
|
|
|
+
|
|
|
+```javascript
|
|
|
+var person = {
|
|
|
+ name: "Ivan",
|
|
|
+ surname: "Ivanovv",
|
|
|
+ "fatherName": "Petrovich",
|
|
|
+}
|
|
|
+
|
|
|
+typeof person
|
|
|
+```
|
|
|
+Нет разницы, определять ключи *литерально* или через строку (в кавычках `"fatherName"`).
|
|
|
+
|
|
|
+Для обращения к элементам по ключу используются следующие нотации:
|
|
|
+
|
|
|
+```javascript
|
|
|
+person.fatherName
|
|
|
+person["name"]
|
|
|
+```
|
|
|
+
|
|
|
+Обратите внимание, что `person.fatherName` работает так же как и `person["name"]`, несмотря на то, что определены по разному.
|
|
|
+
|
|
|
+Для обращения через ключ в переменной используется нотация с квадратными скобками:
|
|
|
+```javascript
|
|
|
+var key = "surname";
|
|
|
+
|
|
|
+person[key]
|
|
|
+person.key
|
|
|
+```
|
|
|
+
|
|
|
+Если просто написать `person.key`, то **JavaScript** будет искать ключ `key` *литерально*, а не по значению переменной `key` ("surname")
|
|
|
+
|
|
|
+Вы можете определить новый элемент массива просто присвоив ему значение:
|
|
|
+
|
|
|
+```javascript
|
|
|
+person.age = 98;
|
|
|
+
|
|
|
+person
|
|
|
+```
|
|
|
+
|
|
|
+Также можно создавать массив через конструктор Object:
|
|
|
+```javascript
|
|
|
+
|
|
|
+var a = new Object();
|
|
|
+a.name = "Petr"
|
|
|
+a.surname = "Petrov";
|
|
|
+a["age"] = 17;
|
|
|
+```
|
|
|
+
|
|
|
+Получить ключи ассоциативного массива можно с помощью функции `Object.keys`:
|
|
|
+```javascript
|
|
|
+Object.keys(person)
|
|
|
+```
|
|
|
+
|
|
|
+В качестве значений в ассоциативном массиве могут быть любые типы данных, в том числе и другие ассоциативные массивы:
|
|
|
+```javascript
|
|
|
+var someTree = {
|
|
|
+ tag: "table", //html tag
|
|
|
+ nestedTags: [ //вложенные тэги
|
|
|
+ {
|
|
|
+ tag: "tr",
|
|
|
+ nestedTags: [
|
|
|
+ {
|
|
|
+ tag: "td",
|
|
|
+ content: "some text",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ tag: "td",
|
|
|
+ content: "some text 2",
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ options:
|
|
|
+ {
|
|
|
+ border: 1,
|
|
|
+ },
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+Нет сложностей с циклическими ссылками:
|
|
|
+```javascript
|
|
|
+var a = {}
|
|
|
+var b = {}
|
|
|
+a.b = b
|
|
|
+b.a = a
|
|
|
+
|
|
|
+b.b = b
|
|
|
+a.a = a
|
|
|
+
|
|
|
+a.name = "A"
|
|
|
+b.name = "B"
|
|
|
+```
|
|
|
+
|
|
|
+## `in`
|
|
|
+
|
|
|
+Ключевое слово `in` используется для двух задач:
|
|
|
+- проверка наличия ключа в ассоциативном массиве
|
|
|
+
|
|
|
+```javascript
|
|
|
+"fatherName" in a
|
|
|
+"age" in person
|
|
|
+```
|
|
|
+
|
|
|
+- конструкция `for (var key in arr)` для перебора всех элементов ассоциативного массива
|
|
|
+
|
|
|
+```javascript
|
|
|
+for (var key in person){
|
|
|
+ console.log(key+": "+person[key]);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+### Задание
|
|
|
+Нарисовать HTML таблицу из двух колонок, в которой слева будут ключи, а справа - значения:
|
|
|
+<table><tr><th>name</th><td>Ivan</td></tr><tr><th>surname</th><td>Ivanovv</td></tr><tr><th>fatherName</th><td>Petrovich</td></tr></table>
|
|
|
+
|
|
|
+## JSON
|
|
|
+
|
|
|
+[**JSON**](http://www.json.org/json-ru.html) (**JavaScript Object Notation**) - синтаксис для хранения древовидных структур данных, который вы видели в примерах выше. Удобен, лаконичен и
|
|
|
+нагляден. Строки в формате **JSON** удобно передавать для обмена данными по сети.
|
|
|
+
|
|
|
+- **Сериализацией** назывют преобразование внутренних структур языка программирования в формат, пригодный для хранения; Обычно это строка того или иного формата
|
|
|
+- **Десериализацией** называют обратное преобразование.
|
|
|
+
|
|
|
+```javascript
|
|
|
+JSON.stringify(someTree)
|
|
|
+JSON.stringify(a)
|
|
|
+JSON.parse('{"country": "Ukraine", "city": "Kharkiv"}')
|
|
|
+```
|
|
|
+
|
|
|
+JSON более строг, чем схожий синтаксис в JavaScript:
|
|
|
+- он требует двойных кавычек вокруг ключей;
|
|
|
+- одинарные кавычки использовать нельзя;
|
|
|
+- невозможно превратить в JSON-строку объекты с циклическими ссылками;
|
|
|
+- поля-методы (функции) не сериализуются
|
|
|
+- после последней пары ключ-значение (перед фигурной скобкой) **не** должно быть запятой. В **JS** это допустимо.
|
|
|
+
|
|
|
+## **ES6**
|
|
|
+
|
|
|
+В стандарте языка **ES6** есть дополнительные возможности работы с объктами:
|
|
|
+
|
|
|
+### дублирование ключа-значения и выражение в ключе
|
|
|
+
|
|
|
+```javascript
|
|
|
+var obj = {
|
|
|
+ name, //name: name
|
|
|
+ ["a" + 'ge']: age, //выражение в ключе,
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### rest/spread `...`
|
|
|
+
|
|
|
+```javascript
|
|
|
+var obj2 = {...obj, surname: ''} //копируем obj и добавляем еще ключ
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+## Деструктуризация
|
|
|
+
|
|
|
+**Деструктуризация** позволяет доставать значения полей объектов и массивов по нескольку за одну операцию и избавляет вас от заведения временной переменной для хранения массива или объекта:
|
|
|
+```javascript
|
|
|
+var [a,b,c] = [1,2,3] //создается три переменных из массива
|
|
|
+var {rand1: x, rand2: y, rand3: z} = {rand1: Math.random(), rand2: Math.random(), rand3: Math.random()}
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+## `for .. of`
|
|
|
+
|
|
|
+Работает как `for in` (почти), но перебирает *значения*, а не *ключи*:
|
|
|
+
|
|
|
+```javascript
|
|
|
+for (let word of ['foo','bar']){
|
|
|
+ console.log(word)
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+## Шаблонизация строк `` `
|
|
|
+
|
|
|
+Символ `` ` (*backtick*, обратная кавычка, находится на `Ё`) позволяет вставить выражение в строку без использования конкатенации:
|
|
|
+
|
|
|
+```javascript
|
|
|
+alert(`Привет, ${prompt('Имя?')}`)
|
|
|
+```
|