for/of , Map Objects and Set Objects
Published: 2022-02-13 18:36:49


In this blog we will cover three es6 features `For...of` , `Map Objects` and `Set Objects`.

These are features that were added in the ES6 version of javascript.

Let’s start with the `for...of` statement.

### for...of

- The **`for...of`**  statement creates a loop iterating over iterable objects that include built-in String, Array ,array-like objects (e.g. arguments or NodeList, TypedArray, Map, Set, and user-defined iterables. It invokes a custom iteration hook with statements to be executed for the value of each distinct property of the object.

`syntax` :

```jsx
for (variable of iterable) {
  statement
}
```

- `variable` : On each iteration a value of a different property is assigned to `variable` . `variable`may be declared with `const`, `let`, or `var`.
- `iterable` : Object whose iterable properties are iterated.

`example`

`Iterating over an Array`

```jsx
const array = ['a', 'b', 'c'];

for (const element of array) {
  console.log(element);
}

/* 
 expected output: "a"
 expected output: "b"
 expected output: "c"
*/
```

 `Iterating over a String`

```jsx
const iterable = 'javascript';

for (const value of iterable) {
  console.log(value);
}
// "j"
// "a"
// "v"
// "a"
// "s"
// "c"
// "r"
// "i"
// "p"
// "t"
```

`Iterating over a Map`

```jsx
const iterable = new Map([['a', 1], ['b', 2], ['c', 3], ['d', 4]]);

for (const entry of iterable) {
  console.log(entry);
}
// ['a', 1]
// ['b', 2]
// ['c', 3]
// ['d', 4]
for (const [key, value] of iterable) {
  console.log(value);
}
// 1
// 2
// 3
// 4
```

---

### Map Objects

- Objects are used for storing keyed collections.
- Arrays are used for storing ordered collections.

But that’s not enough for real life. That’s why `Map` and `Set` also exist.

> Map is a collection of keyed data items, just like an `Object`. But the main difference is that `Map` allows keys of any type.
> 

Methods and properties are:

- `new Map()` – creates the map.
- `map.set(key, value)` – stores the value by the key.
- `map.get(key)` – returns the value by the key, `undefined` if `key` doesn’t exist in map.
- `map.has(key)` – returns `true` if the `key` exists, `false` otherwise.
- `map.delete(key)` – removes the value by the key.
- `map.clear()` – removes everything from the map.
- `map.size` – returns the current element count.

```jsx
let map = new Map();

map.set('1', 'str');   // a string key
map.set(1, 'num');     // a numeric key
map.set(true, 'bool'); // a boolean key

// Map keeps the type, so these two are different:
alert( map.get(1)   ); // 'num'
alert( map.get('1') ); // 'str'

alert( map.size ); // 3
```

As we can see, unlike objects, keys are not converted to strings. Any type of key is possible.

<aside>
💡 **`map[key]` isn’t the right way to use a `Map`.**

Although `map[key]` also works, e.g. we can set `map[key] = 2`, this is treating `map` as a plain JavaScript object, so it implies all corresponding limitations (only string/symbol keys and so on).

So we should use `map` methods: `set`, `get` and so on.

</aside>

`Iteration over Map`

For looping over a map, there are 3 methods:

- `map.keys()` – returns an iterable for keys,
- `map.values()` – returns an iterable for values,
- `map.entries()` – returns an iterable for entries [key, value], it’s used by default in for..of.

```jsx
let superheroes = new Map([
  ['batman', 500],
  ['superman', 350],
  ['wonder woman', 5000]
]);

// iterate over keys (superhero)
for (let superhero of superheroes.keys()) {
  alert(superhero); // batman, superman, wonder woman
}

// iterate over values (power)
for (let power of superheroes.values()) {
  alert(power); // 500, 350, 5000
}

// iterate over [key, value] entries
for (let entry of superheroes) { // the same as of superheroes.entries()
  alert(entry); // 'batman', 500 (and so on)
}
```

<aside>
💡 **The insertion order is used.**
The iteration goes in the same order as the values were inserted. `Map` preserves this order, unlike a regular `Object`.

</aside>

---

### Set Objects

A `Set`is a special type collection – “set of values” (without keys), where each value may occur only once.

Its main methods are:

- `new Set(iterable)` – creates the set, and if an `iterable` object is provided (usually an array), copies values from it into the set.
- `set.add(value)` – adds a value, returns the set itself.
- `set.delete(value)` – removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`.
- `set.has(value)` – returns `true` if the value exists in the set, otherwise `false`.
- `set.clear()` – removes everything from the set.
- `set.size` – is the elements count.

The main feature is that repeated calls of `set.add(value)` with the same value will not do anything. That’s the reason each value occurs  only once in a `Set`.

```jsx
let set = new Set();

let john = { name: "Ram" };
let pete = { name: "Shaym" };
let mary = { name: "Krishna" };

set.add(Ram);
set.add(Shaym);
set.add(Krishna);
set.add(Ram);
set.add(Krishna);

// set keeps only unique values
alert( set.size ); // 3

for (let user of set) {
  alert(user.name); // Ram (then Shaym and Krishna)
}
```

The same methods `Map` has for iterators are also supported:

- `set.keys()` – returns an iterable object for values,
- `set.values()` – same as `set.keys()`, for compatibility with `Map`,
- `set.entries()` – returns an iterable object for entries `[value, value]`, exists for compatibility with `Map`.

---

### Summary.

`Map` – is a collection of keyed values.

Methods and properties:

- `new Map([iterable])` – creates the map, with optional `iterable` (e.g. array) of `[key,value]` pairs for initialization.
- `map.set(key, value)` – stores the value by the key, returns the map itself.
- `map.get(key)` – returns the value by the key, `undefined` if `key` doesn’t exist in map.
- `map.has(key)` – returns `true` if the `key` exists, `false` otherwise.
- `map.delete(key)` – removes the value by the key, returns `true` if `key` existed at the moment of the call, otherwise `false`.
- `map.clear()` – removes everything from the map.
- `map.size` – returns the current element count.

The differences from a regular `Object`:

- Any keys, objects can be keys.
- Additional convenient methods, the `size` property.

`Set` – is a collection of unique values.

Methods and properties:

- `new Set([iterable])` – creates the set, with optional `iterable` (e.g. array) of values for initialization.
- `set.add(value)` – adds a value (does nothing if `value` exists), returns the set itself.
- `set.delete(value)` – removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`.
- `set.has(value)` – returns `true` if the value exists in the set, otherwise `false`.
- `set.clear()` – removes everything from the set.
- `set.size` – is the elements count.

Iteration over `Map` and `Set` is always in the insertion order, so we can’t say that these collections are unordered, but we can’t reorder elements or directly get an element by its number.

---

If this blog helped you learn something new do drop a like.