Functions

Function is a block of code designed to perform a particular task, executed when called or invoked.

Declarations

Function

JAVASCRIPT
function functionName(param) {
// code to be executed
}

Function Expression

TEXT
-  *Not [[03. Hoisting|hoisted]]*
JAVASCRIPT
const functionName = function (param) {
// code to be executed
}

Arrow Function

TEXT
- Un-named function, also called as lambda functions
JAVASCRIPT
const functionName = (param) => {
// code to be executed
}

Types

1. Anonymous function

  • Functions without a name, often used as arguments or assigned to variables.

2. Named functions

  • With a specific name.

3. Immediately invoked functions ( IIFE )

  • Immediately executed after defined.

Scope

  • Scope of function is the function in which it is declared or the whole program if defined in top level

Hoisting

Function declarations and generator functions are value hoisted. Function expressions are not hoisted. Refer - Hoisting

Closures

  • A function that retains access to its outer scope variables. Before ES6, this was the way to emulate private variables.
  • Lexical Environment is created when a function is declared, so closures only form when a function is declared inside a function.

Callbacks

  • A function which is passed as an argument to another function. Now the parent function can call this function after some tasks
JAVASCRIPT
function parent(cb) {
	setTimeout(()=>{
		console.log("Time elapsed");
		cb("Called callback");
	}, 100);
}

function callbackDemoFunction(message) {
	console.log(message);
}

Higher-Order Functions

  • Function that takes one or more arguments as a function or returns a function.

Default Parameter in a function

JAVASCRIPT
function greet(name = 'Guest') {
  console.log(`Hello, ${name}`);
}
greet(); // Hello, Guest
greet('Alice'); // Hello, Alice

Spread operator

  • Allows iterable to be expanded in places where 0 or more arguments or elements are expected
JAVASCRIPT
const numbers = [1, 2, 3];
console.log(Math.max(...numbers)); // 3

function sum(a, b, c) {
  return a + b + c;
}
console.log(sum(...numbers)); // 6

Rest Parameter

  • The rest parameter is a syntax that allows a function to take indefinite parameters in an array. This was introduced in ES6.
JAVASCRIPT
function sum(...theArgs) {
  let total = 0;
  for (const arg of theArgs) {
    total += arg;
  }
  return total;
}

console.log(sum(1, 2, 3));
// Expected output: 6
  • In ES5, arguments variable used to be present, which consists of all the parameters passed, but this was not a true array and forEach, map array methods were not present.

Function binding

  • Here greet is a method of person, which refers to name in the object context.
JAVASCRIPT
const person = {
	name : "Adesh",
	greet: function() {
		console.log("Hello ", this.name);
	}
}

// Calling greet method with the object
person.greet() // Outputs -> Hello Adesh
  • Assigning the greet method to a variable, this makes it lose its context.
JAVASCRIPT
const greetFunc = person.greet;

greetFunc() // Outputs -> undefined
  • bind returns a function with a context for this attached to it.
JAVASCRIPT
const greetFunc = person.greet.bind(person);

// OR

const greeFunc = person.greet.bind({name: "SomeoneElse"});
  • An interesting approach - It works as this refers to the object which owns the method rather than who or where it's defined.
JAVASCRIPT
const person = {
	greet: function (){
		console.log("Hello ",this.name)
	}
}

let anotherPerson = {
	name : "SomeoneElse"
}

anotherPerson.greet = person.greet;

anotherPerson.greet() // Outputs -> Hello SomeoneElse

Asynchronous functions

  • Async/Await: Simplifies working with asynchronous code by allowing you to write asynchronous functions using the async and await keywords.
JAVASCRIPT
async function fetchData() {
  let response = await fetch('https://api.example.com/data');
  let data = await response.json();
  console.log(data);
}

fetchData();

Generator Functions

  • The function defined as function* syntax
  • Generator functions are special type of functions that makes it easy to implement the iterators. When a generator function is called, it returns a generator which can be called only once and it will execute the code till the yield keyword in the function and return the yield value.
JAVASCRIPT
function* makeRangeIterator() {

    let iterationCount = 20;
    for (let i = 0; i < 4; i += 1) {
        iterationCount++;
        yield i;
    }
    return iterationCount
}

const iter = makeRangeIterator();

for(let val of iter) {
    console.log(val);
}
  • The for...of loop exhausts the yields and does not capture the return statement. The return statement is executed or returned after all the yields are exhausted. Below is the example of how to capture the return.
JAVASCRIPT
let result;

while( !result?.done) {
    result = iter.next();
    console.log(result);
}

Functions properties and methods

  • name returns the name of the functions
  • length returns the length of the arguments expected in the function
  • call and apply methods call the function by providing the values for this
JAVASCRIPT
function greet(param) {
    console.log(this);
    console.log(param);
}

const person1 = { name: "Dave" };
greet.call(person1, "John"); // Output -> { name: "Dave" } John

greet.apply(person1, ["John"]); // Output -> { name: "Dave" } John
Adesh Tamrakar
SOFTWARE ENGINEER · VAULT

Notes, insights and random discoveries from a working engineer's vault - written for future me, published for you.