DEV Community

Cover image for Advanced functionality with functions in JavaScript
Unnati Bamania
Unnati Bamania

Posted on

Advanced functionality with functions in JavaScript

Right since 2015, EcmaScript6 has brought many advancements in JavaScript coding practices. A lot of modern stuff is included in JavaScript, which enhances the coding experience and makes writing code easier. Some of the features include spread operator, maps, sets, generators, and a lot more. Let’s explore these features in greater detail.

Spread operator

Spread operators is a new function in JavaScript ES6 version. The spread operator allows an iterable to expand in places where zero or more arguments are expected. It is represented using the ... syntax. It makes shallow copies of objects in JavaScript. You can use the spread operator to concatenate two or more arrays, expand them, calculate the sum of all elements or copy an array.

Consider the following piece of code,

let arr = [1, 2, 3, 4];

function x(){
  console.log(arr);
}
x.apply(null, arr);
Enter fullscreen mode Exit fullscreen mode

Here, you need to use the apply function to print it in the same way. Using the spread operator, the same functionality can be achieved with:

function x(){
  console.log(...arr);
}
Enter fullscreen mode Exit fullscreen mode

Closures

The closure is a function bind with its lexical environment. In simpler terms, a closure is a function inside a function that returns some value.
Consider this simple example,

function outerFunc(){
  let val = 2;
  function innerFunc(){
    console.log(val);
  }
  innerFunc();
}  
outerFunc();
Enter fullscreen mode Exit fullscreen mode

The function outerFunc creates a local variable called val and there's a function named innerFunc inside outerFunc. Since inner functions have access to the outer functions, the innerFunc has access to the variables of outerFunc as well.

So, when you try to print the value of variable val, it will give you output as 2.

Iterators and generators

Iterators and generators are two different concepts but they're used in similar ways. They're used to iterate through arrays and objects in JavaScript.
Iterators are like advanced loops that can be paused and Generators are functions that can be paused and can return multiple values.

Iterators

Here is an example of an iterator

function fruitIter(fruits){
  let index = 0;
  return {
    next: function(){
      return index < fruits.length ? { value: fruits[index++], done: false } : {done: true}
    }
  }
}

const fruitsArray = ["Mango", "Banana", "Grapes"];

const fruits = fruitIter(fruitsArray);
console.log(fruits.next().value); // output: Mango
Enter fullscreen mode Exit fullscreen mode

When the array fruitsArray is passed in fruitIter function, the index is initialized to 0, then it goes into the next function and checks whether the index is greater than fruitArray’s length and returns an object while incrementing the value of the index.

This is how iterators work. If we call the function using fruit iterator again, it will print its value (Banana). If you're done iterating through fruitsArray, the status done will change to false and the value will be undefined.

Generators

Generators are similar to Iterators but they return multiple values. These values are called yield values. Generator functions are written using the function* syntax. * denotes that it is not a normal function but a generator.
Here is an example of generators:

function* printFruits(){

  yield "Mango";
  yield "Banana";
  yield: "Grapes";
}

 const fruit = printFruits();
 console.log(fruit.next()); // Output: { value: "Fruit", done: false }
Enter fullscreen mode Exit fullscreen mode

In this example, yield is the iterator, and when you call the function sayFruit and print fruit.next(), it gives you an object where you get the value and the done status which denotes whether all values are iterated through or not.

Maps

A map is an object that holds key-value pairs. Any object reference type or a primitive can be used as a key or value.

How can you create maps?

const mp1 = new Map();
const key1 = "String",
      key2 = {},
      key3 = function(){}

 // setting map values by key
 mp1.set(key1, "Key 1");
 mp1.set(key2, "Key 2");
 mp1.set(key3, "Key 3");

Enter fullscreen mode Exit fullscreen mode

You can create a map using the new Map() syntax. The key can be of any type: String, Number, function, or object. We use the set keyword to store key-value pairs into the map.

Other functionality with maps

// Get values by keys
console.log(mp1.get(key1);  // Key1

// Get size
console.log(mp1.size) // 3
Enter fullscreen mode Exit fullscreen mode

Iterating through maps

// using for loop
for(let [key, value]of mp1){
    console.log(`${key} -> ${value}`);

 // iterating through keys
 for(let key in mp1.keys()){
    console.log(key);
 }
}

 // iterating through values
 for(let value in mp1.values()){
    console.log(value);
 }
}

Enter fullscreen mode Exit fullscreen mode

Sets

A set is an array that holds unique values in it. You can add anything inside a set: an object, number, boolean, etc.

const s = new Set();

// add values
s.add(2);
s.add(true);
s.add("String");
s.add({name: "sheep"});

// get count
console.log(s.size);

// delete an item
s.delete(2);

Enter fullscreen mode Exit fullscreen mode

Check for value in set

console.log(s.has(2)); // true
console.log(s.has(100)); //false
console.log(s.has({name: "sheep"})); // false

Enter fullscreen mode Exit fullscreen mode

In the above code, if you check whether object {name: "sheep"} exists in the list, then it will return false even though it does exist in the set. This is because object type is nonprimitive in JavaScript. Although both these objects are the same, they point to different memory locations. Hence, that statement returns a false value.

Iterating through sets

for(let x in s){
  console.log(x);
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)