JavaScript supports several types of functions. Here are some commonly used function types in JavaScript:
- Named Function: A function with a specified name that can be called using its name. For example:
function add(a, b) {
return a + b;
}
- Anonymous Function: A function without a name, often assigned to a variable or used as a callback function. For example:
var greet = function() {
console.log("Hello!");
};
- Arrow Function: A concise syntax for writing functions, introduced in ECMAScript 6 (ES6). Arrow functions have implicit returns and lexical scoping of
this
. For example:
var multiply = (a, b) => a * b;
- Immediately Invoked Function Expression (IIFE): A function that is executed immediately after it is defined. It is typically wrapped in parentheses to create a function expression and then immediately invoked. For example:
(function() {
console.log("This is an IIFE.");
})();
- Constructor Function: A function used to create objects based on a template called a constructor. It is typically invoked with the new keyword. For example:
function Person(name, age) {
this.name = name;
this.age = age;
}
var john = new Person("John", 25);
- Generator Function: A special type of function that can be paused and resumed using the yield keyword. Generator functions are defined using the function* syntax. For example:
function* counter() {
var count = 0;
while (true) {
yield count++;
}
}
var iterator = counter();
console.log(iterator.next().value); // 0
console.log(iterator.next().value); // 1
- Recursive Function: A function that calls itself either directly or indirectly. Recursive functions are useful for solving problems that can be divided into smaller sub-problems. For example:
function factorial(n) {
if (n === 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
- Function Declarations: These are created using the
function
keyword, followed by the function name and a pair of parentheses. They can be declared anywhere in the code and are hoisted to the top of their scope.
function functionName(parameters) {
// function body
}
- Function Expressions: These involve assigning a function to a variable or a property of an object. They are not hoisted, so they must be defined before they are used.
var functionName = function(parameters) {
// function body
};
10.) What are lambda or arrow functions
An arrow function is a shorter syntax for a function expression and does not have its own this, arguments, super, or new.target. These functions are best suited for non-method functions, and they cannot be used as constructors.
11.) What is a first-class function?
In Javascript, functions are first-class objects. First-class functions mean when functions in that language are treated like any other variable.
For example, in such a language, a function can be passed as an argument to other functions, returned by another function, and assigned as a value to a variable. For example, in the below example, handler functions assigned to a listener
const handler = () => console.log("This is a click handler function");
document.addEventListener("click", handler);
12.) What is a first-order function?
First-order function is a function that doesn’t accept another function as an argument and doesn’t return a function as its return value.
const firstOrder = () => console.log("I am a first order function!");
13.) What is a higher-order function?
A higher-order function is a function that accepts another function as an argument or returns a function as a return value or both.
const firstOrderFunc = () =>
console.log("Hello, I am a First order function");
const higherOrder = (ReturnFirstOrderFunc) => ReturnFirstOrderFunc();
higherOrder(firstOrderFunc);
14.) What is a unary function?
An unary function (i.e. monadic) is a function that accepts exactly one argument. It stands for a single argument accepted by a function.
Let us take an example of a unary function,
const unaryFunction = (a) => console.log(a + 10); // Add 10 to the given argument and display the value
15.) What is the currying function?
Currying is the process of taking a function with multiple arguments and turning it into a sequence of functions each with only a single argument. Currying is named after the mathematician Haskell Curry. By applying currying, an n-ary function turns it into a unary function.
Let’s take an example of the n-ary function and how it turns into a currying function,
const multiArgFunction = (a, b, c) => a + b + c;
console.log(multiArgFunction(1, 2, 3)); // 6
const curryUnaryFunction = (a) => (b) => (c) => a + b + c;
curryUnaryFunction(1); // returns a function: b => c => 1 + b + c
curryUnaryFunction(1)(2); // returns a function: c => 3 + c
curryUnaryFunction(1)(2)(3); // returns the number 6
Curried functions are great to improve code reusability and functional composition.
16.) What is a pure function?
A Pure function is a function where the return value is only determined by its arguments without any side effects. i.e, If you call a function with the same arguments ‘n’ number of times and ‘n’ number of places in the application then it will always return the same value.
Let’s take an example to see the difference between pure and impure functions,
//Impure
let numberArray = [];
const impureAddNumber = (number) => numberArray.push(number);
//Pure
const pureAddNumber = (number) => (argNumberArray) =>
argNumberArray.concat([number]);
//Display the results
console.log(impureAddNumber(6)); // returns 1
console.log(numberArray); // returns [6]
console.log(pureAddNumber(7)(numberArray)); // returns [6, 7]
console.log(numberArray); // returns [6]
As per the above code snippets, the Push function is impure itself by altering the array and returning a push number index independent of the parameter value. . Whereas Concat on the other hand takes the array and concatenates it with the other array producing a whole new array without side effects. Also, the return value is a concatenation of the previous array.
Remember that Pure functions are important as they simplify unit testing without any side effects and no need for dependency injection. They also avoid tight coupling and make it harder to break your application by not having any side effects. These principles are coming together with the Immutability concept of ES6 by giving preference to const over let usage.