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) ); // 'num1'
|
||||||
alert( map.get('1') ); // 'str1'
|
alert( map.get('1') ); // 'str1'
|
||||||
|
|
||||||
|
alert( map.size ); // 3
|
||||||
```
|
```
|
||||||
|
|
||||||
Как видно из примера выше, для сохранения и чтения значений используются методы `get` и `set`, причём `set` можно чейнить.
|
Как видно из примера выше, для сохранения и чтения значений используются методы `get` и `set`, причём `set` можно чейнить. И ключи и значения сохраняются "как есть", без преобразований типов.
|
||||||
|
|
||||||
|
Свойство `map.size` хранит общее количество записей в `map`.
|
||||||
|
|
||||||
**При создании `Map` можно сразу инициализовать списком значений.**
|
**При создании `Map` можно сразу инициализовать списком значений.**
|
||||||
|
|
||||||
|
@ -62,11 +66,14 @@ alert( visitsCountMap.get(user) ); // 123
|
||||||
|
|
||||||
[smart header="Как map сравнивает ключи"]
|
[smart header="Как map сравнивает ключи"]
|
||||||
Для проверки значений на эквивалентность используется алгоритм [SameValueZero](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-samevaluezero). Он аналогичен строгому равенству `===`, отличие -- в том, что `NaN` считается равным `NaN`.
|
Для проверки значений на эквивалентность используется алгоритм [SameValueZero](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-samevaluezero). Он аналогичен строгому равенству `===`, отличие -- в том, что `NaN` считается равным `NaN`.
|
||||||
|
|
||||||
|
Этот алгоритм жёстко фиксирован в стандарте, его нельзя изменять или задавать свою функцию для него.
|
||||||
[/smart]
|
[/smart]
|
||||||
|
|
||||||
Для удаления записей используется метод:
|
Для удаления записей:
|
||||||
<ul>
|
<ul>
|
||||||
<li>`map.delete(key)` -- возвращает `true`, если ключ существовал, иначе `false`.</li>
|
<li>`map.delete(key)` удаляет запись с ключом `key`, возвращает `true`, если такая запись была, иначе `false`.</li>
|
||||||
|
<li>`map.clear()` -- удаляет все записи, очищает `map`.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Для проверки существования ключа:
|
Для проверки существования ключа:
|
||||||
|
@ -122,6 +129,10 @@ for(let entry of recipeMap) { // то же что и recipeMap.entries()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[smart header="Перебор идёт в том же порядке, что и вставка"]
|
||||||
|
Перебор осуществляется в порядке вставки. Объекты `Map` гарантируют это, в отличие от обычных объектов `Object`.
|
||||||
|
[/smart]
|
||||||
|
|
||||||
Кроме того, у `Map` есть стандартный методы `forEach`, аналогичный массиву:
|
Кроме того, у `Map` есть стандартный методы `forEach`, аналогичный массиву:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -140,17 +151,134 @@ recipeMap.forEach( (value, key, map) => {
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
У `Map` есть и другие свой методы:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Есть и другие методы:
|
|
||||||
|
|
||||||
<ul>
|
<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