es5
This commit is contained in:
parent
c978fe73c1
commit
ff23414aed
1 changed files with 140 additions and 12 deletions
|
@ -24,9 +24,13 @@ map
|
|||
// в обычном объекте это было бы одно и то же
|
||||
alert( map.get(1) ); // 'num1'
|
||||
alert( map.get('1') ); // 'str1'
|
||||
|
||||
alert( map.size ); // 3
|
||||
```
|
||||
|
||||
Как видно из примера выше, для сохранения и чтения значений используются методы `get` и `set`, причём `set` можно чейнить.
|
||||
Как видно из примера выше, для сохранения и чтения значений используются методы `get` и `set`, причём `set` можно чейнить. И ключи и значения сохраняются "как есть", без преобразований типов.
|
||||
|
||||
Свойство `map.size` хранит общее количество записей в `map`.
|
||||
|
||||
**При создании `Map` можно сразу инициализовать списком значений.**
|
||||
|
||||
|
@ -62,11 +66,14 @@ alert( visitsCountMap.get(user) ); // 123
|
|||
|
||||
[smart header="Как map сравнивает ключи"]
|
||||
Для проверки значений на эквивалентность используется алгоритм [SameValueZero](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-samevaluezero). Он аналогичен строгому равенству `===`, отличие -- в том, что `NaN` считается равным `NaN`.
|
||||
|
||||
Этот алгоритм жёстко фиксирован в стандарте, его нельзя изменять или задавать свою функцию для него.
|
||||
[/smart]
|
||||
|
||||
Для удаления записей используется метод:
|
||||
Для удаления записей:
|
||||
<ul>
|
||||
<li>`map.delete(key)` -- возвращает `true`, если ключ существовал, иначе `false`.</li>
|
||||
<li>`map.delete(key)` удаляет запись с ключом `key`, возвращает `true`, если такая запись была, иначе `false`.</li>
|
||||
<li>`map.clear()` -- удаляет все записи, очищает `map`.</li>
|
||||
</ul>
|
||||
|
||||
Для проверки существования ключа:
|
||||
|
@ -122,6 +129,10 @@ for(let entry of recipeMap) { // то же что и recipeMap.entries()
|
|||
}
|
||||
```
|
||||
|
||||
[smart header="Перебор идёт в том же порядке, что и вставка"]
|
||||
Перебор осуществляется в порядке вставки. Объекты `Map` гарантируют это, в отличие от обычных объектов `Object`.
|
||||
[/smart]
|
||||
|
||||
Кроме того, у `Map` есть стандартный методы `forEach`, аналогичный массиву:
|
||||
|
||||
```js
|
||||
|
@ -140,17 +151,134 @@ recipeMap.forEach( (value, key, map) => {
|
|||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Есть и другие методы:
|
||||
У `Map` есть и другие свой методы:
|
||||
|
||||
<ul>
|
||||
<li>`map.size()` -- количество записей в
|
||||
<li>`map.size()` -- возвращает количество записей,</li>
|
||||
<li>`map.clear()` -- удаляет все записи.</li>
|
||||
</ul>
|
||||
|
||||
## Set
|
||||
|
||||
`Set` -- коллекция для хранения множества значений, причём каждое значение может встречаться лишь один раз.
|
||||
|
||||
Например, к нам приходят посетители, и мы хотели бы сохранять всех, кто пришёл. Повторные визиты не должны приводить к дубликатам.
|
||||
|
||||
`Set` для этого отлично подходит:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
'use strict';
|
||||
|
||||
let set = new Set();
|
||||
|
||||
let vasya = {name: "Вася"};
|
||||
let petya = {name: "Петя"};
|
||||
let dasha = {name: "Даша"};
|
||||
|
||||
// посещения
|
||||
set.add(vasya);
|
||||
set.add(petya);
|
||||
set.add(dasha);
|
||||
set.add(vasya);
|
||||
set.add(petya);
|
||||
|
||||
alert( set.size ); // 3
|
||||
|
||||
set.forEach( user => alert(user.name ) ); // Вася, Петя, Даша
|
||||
```
|
||||
|
||||
В примере выше многократные добавления одного и того же объекта в `set` не создают лишних копий.
|
||||
|
||||
Альтернатива `Set` -- это массивы с поиском дубликата при каждом добавлении, но это гораздо хуже по производительности. Или же объекты, где в качестве ключа выступает какой-нибудь уникальный идентификатор посетителя. Но это менее удобно, чем простой и наглядный `Set`.
|
||||
|
||||
Основные методы:
|
||||
<ul>
|
||||
<li>`set.add(item)` -- добавляет в коллекцию `item`, возвращает `set` (чейнится).</li>
|
||||
<li>`set.delete(item) -- удаляет `item` из коллекции, возвращает `true`, если он там был, иначе `false`.</li>
|
||||
<li>`set.has(item)` -- возвращает `true`, если `item` есть в коллекции, иначе `false`.</li>
|
||||
<li>`set.clear()` -- очищает `set`.</li>
|
||||
</ul>
|
||||
|
||||
Перебор `Set` осуществляется через `forEach` или `for..of` аналогично `Map`:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
'use strict';
|
||||
|
||||
let set = new Set(["апельсины", "яблоки", "бананы"]);
|
||||
|
||||
// то же, что: for(let value of set)
|
||||
set.forEach((value, valueAgain, set) => {
|
||||
alert(value); // апельсины, затем яблоки, затем бананы
|
||||
});
|
||||
```
|
||||
|
||||
Заметим, что в `Map` у функции в `.forEach` три аргумента: ключ, значение, объект `map`.
|
||||
|
||||
В `Set` для совместимости с `Map` сделано похожим образом -- у `.forEach`-функции также три аргумента. Но первые два всегда совпадают и содержат очередное значение множества.
|
||||
|
||||
## WeakMap и WeakSet
|
||||
|
||||
`WeakSet` -- особый вид `Set` не препятствующий сборщику мусора. То же самое -- `WeakMap` для `Map`.
|
||||
|
||||
То есть, если некий объект присутствует только в `WeakSet/WeakMap` -- он удаляется из памяти.
|
||||
|
||||
Это нужно для тех ситуаций, когда сами объекты используются где-то в другом месте кода, а здесь мы хотим хранить для них "вспомогательные" данные, существующие лишь пока жив объект.
|
||||
|
||||
Например, у нас есть элементы на странице или, к примеру, пользователи, и мы хотим хранить для них вспомогательную инфомацию, например обработчики событий или просто данные, но действительные лишь пока объект, к которому они относятся, существует.
|
||||
|
||||
Если поместить такие данные в `WeakMap`, а объект сделать ключом, то они будут автоматически удалены из памяти, когда удалится элемент.
|
||||
|
||||
Например:
|
||||
```js
|
||||
// текущие активные пользователи
|
||||
let activeUsers = [
|
||||
{name: "Вася"},
|
||||
{name: "Петя"},
|
||||
{name: "Маша"}
|
||||
];
|
||||
|
||||
// вспомогательная информация о них,
|
||||
// которая напрямую не входит в объект юзера,
|
||||
// и потому хранится отдельно
|
||||
let weakMap = new WeakMap();
|
||||
|
||||
weakMap[activeUsers[0]] = 1;
|
||||
weakMap[activeUsers[1]] = 2;
|
||||
weakMap[activeUsers[2]] = 3;
|
||||
|
||||
alert( weakMap[activeUsers[0]].name ); // Вася
|
||||
|
||||
activeUsers.splice(0, 1); // Вася более не активный пользователь
|
||||
|
||||
// weakMap теперь содержит только 2 элемента
|
||||
|
||||
activeUsers.splice(0, 1); // Петя более не активный пользователь
|
||||
|
||||
// weakMap теперь содержит только 1 элемент
|
||||
```
|
||||
|
||||
TODO WRITE MORE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ToDo
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue