aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/guide/keyed_collections/index.html
blob: 62de077e0cc6b997f90ff8e31106c844e767ad7f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
---
title: Коллекции
slug: Web/JavaScript/Guide/Keyed_collections
tags:
  - коллекции
  - словари
  - структура данных
translation_of: Web/JavaScript/Guide/Keyed_collections
---
<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}</div>

<p class="summary">Этот раздел содержит обзор коллекций {{jsxref("Set")}} и словарей {{jsxref("Map")}} - встроенных {{Glossary("Data_structure","структур данных")}} с доступом по ключу.</p>

<h2 id="Словари">Словари</h2>

<h3 id="Тип_Map"><code>Тип Map</code> </h3>

<p>{{jsxref("Map")}} - реализация простого ассоциативного массива (словаря). Он содержит данные в виде набора пар ключ/значение(ключи уникальны) и предоставляет методы для доступа и манипулирования этими данными.  </p>

<p>Также как и {{jsxref("Object", "объект", "", 1)}}, словарь позволяет</p>

<ul>
 <li>получать значение  по ключу, а также проверять наличие ключа</li>
 <li>добавлять/удалять пары ключ/значение</li>
 <li>перезаписывать значение по ключу (ключи уникальны).</li>
 <li>итерироваться по ключам</li>
</ul>

<p>Словари, как специализированная структура данных, имеют существенные преимущества по сравнению с объектами<font face="Consolas, Liberation Mono, Courier, monospace">:</font></p>

<ul>
 <li>Ключи словаря могут быть любого типа (а не только строки).</li>
 <li>Словарь хранит свой размер (не надо вычислять).</li>
 <li>Натуральный порядок обхода элементов ( в порядке добавления) с помощью {{jsxref("Statements/for...of","for...of")}}.</li>
 <li>Словарь не подмешивает ключи из прототипа (в отличие от объекта).</li>
</ul>

<p>В следующем примере приведены основные операции со словарём:</p>

<pre class="brush: js">var sayings = new Map();
sayings.set("dog", "woof");
sayings.set("cat", "meow").set("elephant", "toot");
//вызов функции .set возвращает Map, поэтому set можно объединять в цепочки

sayings.set("dog", "гав-гав"); // заменить значение по ключу

sayings.size; // 3
sayings.get("fox"); // undefined
sayings.has("bird"); // false
sayings.delete("dog");

for (var [key, value] of sayings) {
  console.log(key + " goes " + value);
}
// "cat goes meow"
// "elephant goes toot"
</pre>

<p>Больше примеров и полное описание на странице справочника {{jsxref("Map")}} .</p>

<h3 id="Тип_WeakMap"><code>Тип WeakMap</code> </h3>

<p>{{jsxref("WeakMap")}} это специальный вид словаря, <strong>ключами которого могут быть только объекты</strong>, причём ссылки на них в WeakMap являются  <em>слабыми </em>(не учитываются  сборщиком мусора (garbage collector GC)).</p>

<div class="note">
<p>Интерфейс <code>WeakMap</code> совпадает с <code>Map</code>, единственное отличие - <strong>ключи <code>WeakMap</code> нельзя итерировать</strong> (т.e. нельзя получить список ключей). Это понятно, поскольку в таком случае возникла бы неопределённость с достоверностью этого списка в зависимости от состояния garbage collection.</p>
</div>

<p>Больше примеров, полное описание, а также обсуждение "Зачем <em>WeakMap</em>?"  на странице справочника {{jsxref("WeakMap")}}.</p>

<p>Отметим, что <code>WeakMap,</code> в частности, может элегантно использоваться для упаковки приватных данных или деталей реализации. Следующий пример из статьи Nick Fitzgerald <a href="http://fitzgeraldnick.com/weblog/53/">"Hiding Implementation Details with ECMAScript 6 WeakMaps"</a>. Приватная часть сохраняется как значение в <code>privates</code> и имеет время жизни такое же как и сущность класса. Сам класс и его методы публичны; прочее недоступно извне модуля:</p>

<pre class="brush: js">const privates = new WeakMap();

export class Public() {

  constructor() {
    const me = {
    // Приватные данные идут здесь
    };
    // 'me' будет освобождён вместе с 'this' !!!
    privates.set(this, me);
  }

  method () {
    const me = privates.get(this);
    // Сделайте что-нибудь с приватными данными в 'me'...
  }
}
</pre>

<h2 id="Коллекции">Коллекции</h2>

<h3 id="Тип_Set"><code>Тип Set</code> </h3>

<p>{{jsxref("Set")}} реализация коллекции - структура данных, которая содержит список уникальных элементов в порядке их добавления. </p>

<p>В следующем примере приведены основные операции по работе с коллекцией <code>Set:</code></p>

<pre class="brush: js">var mySet = new Set();
mySet.add(1);
mySet.add("some text");
mySet.add("foo");

mySet.has(1); // true
mySet.delete("foo");
mySet.size; // 2

for (let item of mySet) console.log(item);
// 1
// "some text"
</pre>

<p>Больше примеров и полное описание на странице справочника {{jsxref("Set")}}</p>

<h4 id="Преобразования_между_Array_и_Set">Преобразования между Array и Set</h4>

<p>Можно создать {{jsxref("Array")}} из Set с помощью {{jsxref("Array.from")}} или используя <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator">spread operator</a>.</p>

<p>В свою очередь, конструктор <code>Set</code> может принимать <code>Array</code> в качестве аргумента.</p>

<div class="note">
<p>Поскольку <code>Set</code> структура работает с уникальными значениями, любые повторяющиеся элементы из Array будут проигнорированы.</p>
</div>

<pre class="brush: js">Array.from(mySet);
[...mySet2];

mySet2 = new Set([1,2,3,4]);
</pre>

<h4 id="Сравнение_Array_и_Set"><code>Сравнение Array</code> и <code>Set</code> </h4>

<p>Словари, как специализированная структура данных, имеют существенные отличия по сравнению с массивами:</p>

<ul>
 <li>{{jsxref("Set.has")}} работает быстрее чем {{jsxref("Array.indexOf")}}.</li>
 <li><font face="Consolas, Liberation Mono, Courier, monospace">можно удалять элементы по значению (а не по индексу как массивах)</font>.</li>
 <li>{{jsxref("NaN")}} обрабатывается корректно.</li>
 <li><font face="Consolas, Liberation Mono, Courier, monospace">поддерживается уникальность значений</font>.</li>
</ul>

<h3 id="Тип_WeakSet"><code>Тип WeakSet</code> </h3>

<p>{{jsxref("WeakSet")}} это специальный вид коллекции, элементами которой могут быть только объекты. Ссылки на эти объекты в WeakSet являются <em>слабыми </em>(не учитываются  сборщиком мусора (garbage collector GC)).</p>

<div class="note">
<p>Элементы <code>WeakSet</code> уникальны и могут быть добавлены только один раз, также как и в {{jsxref("Set")}}</p>
</div>

<p>Основные отличия от {{jsxref("Set")}}:</p>

<ul>
 <li><code>WeakSet</code> это коллекция <em>объектов</em> ( примитивные значения не могут быть добавлены).</li>
 <li><code>WeakSet</code> <em>нельзя итерировать</em>. А также нельзя получить список (итератор) элементов.</li>
</ul>

<p>Использование <code>WeakSet</code> достаточно специфическое. Пользуясь тем, что они не могут создавать утечек памяти, в них можно, например, безопасно помещать ссылки на DOM элементы.</p>

<p>Больше примеров и полное описание на странице справочника {{jsxref("WeakSet")}}</p>

<h2 id="Проверка_на_равенство_в_Map_и_Set">Проверка на равенство в <code>Map</code> и <code>Set</code></h2>

<p>Сравнение на равенство ключей в <code>Map</code> objects или объектов в <code>Set</code> основано на "<a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero">same-value-zero algorithm</a>":</p>

<ul>
 <li>алгоритм сравнения в целом совпадает с оператором <code>===</code>.</li>
 <li><code>-0</code> и <code>+0</code> считаются равными (в отличие от <code>===</code>).</li>
 <li>{{jsxref("NaN")}} считается равным самому себе (в отличие от <code>===</code>).</li>
</ul>

<p>{{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}</p>