Demystifying Functions
So today we are going to discuss some popular interview questions on functions which is a very important topic in JS and obviously also required a lot in development.
What are Functions in JS?
According to MDN Web Docs,
Functions are one of the fundamental building blocks in JavaScript. A function in JavaScript is similar to a procedure—a set of statements that performs a task or calculates a value, but for a procedure to qualify as a function, it should take some input and return an output where there is some obvious relationship between the input and the output. To use a function, you must define it somewhere in the scope from which you wish to call it
Lets go and solve some popular interview questions asked on functions.
What is a Function Declaration or Statement?
function addTwoNumbers(a,b){
return (a+b);
Above is an example of a simple function decalration or statement.
What is Function Expression?
Whenever a function is stored inside of a variable then it is known as a function expression since the function is present as an expression .
const addTwoNumbers=function(a,b){
return (a+b);
}
Addon Question: what can we call this function? Anonymous function since it is not directly given a name but its name is the same as the variable name and using that you can call it.
addTwoNumbers(4,5);
Below is the screenshot of the working result:
What are First Class Functions?
MDN Web Docs has got an awesome defintion for this :
A programming language is said to have First-class functions 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, can be returned by another function and can be assigned as a value to a variable.
Lets take an example:
function square(num){
return num*num;
}
function displaySquare(fn){
console.log("Square of 5="+fn(5));
}
displaySquare(square);//here as you can see that the square function's
//reference is passed as an argument and gets stored in fn and then later
//fn(5) , the square function gets called by sending 5 as parameter
Here is a screenshot of the working of the code:
What is an IIFE?
An IIFE (Immediately Invoked Function Expression) is a JS function that runs as soon as it is defined.
Lets see an example:
(function sum2(a,b){
console.log(a+b);
})(4,5);//as you can see the fn gets immediately called with 4 and 5 as
//parameters
Heres the output:
Follow up question : have a look at the code below and try to solve it before seeing the working:
(function (x){
return (function (y){
console.log(x);
})(2)}
)(1);
Working: so whats occuring here is the outside function gets immediately called with x receiving 1 and then inner function gets called with y receiving 2 but in the console x's value get displayed which is 1.
Proof:
Questions related to Function Scope
Lets do some warmup first. This is an example taken directly from MDN Web Docs.
// The following variables are defined in the global scope
const num1 = 20;
const num2 = 3;
const name = "Chamakh";
// This function is defined in the global scope
function multiply() {
return num1 * num2;//global variables num1 and num2 being used
}
console.log(multiply()); // 60
// A nested function example
function getScore() {
const num1 = 2;
const num2 = 3;
//local variables num1 and num2 shadow global ones
function add() {
return `${name} scored ${num1 + num2}`;
}
return add();
}
console.log(getScore()); // "Chamakh scored 5"
Having done our warmup ,lets see the followup question. Have a look at both of the loops and try to figure out the difference in output.
for(let i=0;i<5;i++)
{
setTimeout(function(){
console.log(i)},i*1000);
}
for(var i=0;i<5;i++)
{
setTimeout(function (){
console.log(i)},i*1000);
}
So guess what for the first one the output would be :0 1 2 3 4 (each after one second delay) and for the second one it would be :5 5 5 5 5 (each after one second delay).
Lets see ChatGPT's reason for this :
For the first snippet, let
creates a new binding fori
in each iteration of the loop. So, when the setTimeout functions execute, they capture the value ofi
at that iteration. The delay for each setTimeout increases by 1000 milliseconds for each iteration.
And for the second snippet, var
does not create a new binding fori
in each iteration of the loop. So, when the setTimeout functions execute, they use the final value ofi
after the loop has finished executing. The delay for each setTimeout increases by 1000 milliseconds for each iteration.
You can always use ChatGPT to clear your doubts on "popular" topics. But still try to double check.
Questions related to hoisting in function
A normal function is hoisted completely and hence a function call before or after the function definition does not affect the result. Lets see an example .
console.log(addTwoNumbers(4,5));
function addTwoNumbers(a,b){
return (a+b);
}
console.log(addTwoNumbers(4,5));
As you can see the output remains the same:
Follow up: view the code below and predict the output.
var x=21;
var fn=function(){
console.log(x);
var x=20;
}
fn();
You might have thought since var x = 20
is yet to be executed so it will print 21
from global context but , undefined
is the answer since a separate execution cotext is created for the function and here the local variable is internally hoisted and hence it returns undefined
.
Proof:
Params vs Arguments
Simple stuff.
function hello(a,b)//formal parameters also known as params
{
return "hello"
}
hello(4,5);//actual parameters also known as arguments
Rest vs Spread Operator
Lets see an example for this one.
function addTwoNumbers(...nums)//here the "rest" operator takes up the
//incoming values in an array which you can understand by the output as well
{
console.log(nums);
console.log("Addition of two given numbers is:"+(nums[0]+nums[1]));
}
var input=[5,6];
addTwoNumbers(...input);//its the same as addTwoNumbers(5,6) where the "spread"
//operator spreads the values of the array in the arguments zone
Lets see the output:
Follow up question: view the code below and figure out the answer.
function something(a,b,c,...numbers)//always keep the rest operator or spread
//operator at the end
{
console.log(a,b,c,numbers);
}
something(5,6,7,8,9,0,1);
Lets see if your answer is correct.
What are Callback Functions
We have discussed callback functions before in map,filter and reduce and saw its application .Still lets go through a MDN Web Docs defintion and example.
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.
Lets look at an example:
function givename()
{
return "Mainak";
}
function printName(callback)//givename is recieved as callback and can be
//called using callback()
{
console.log(callback());
}
printName(givename);//givename is passed as callback
The output:
What are arrow functions?
According to MDN Web Docs, an arrow function expression is a compact alternative to a traditional function expression, with some semantic differences and deliberate limitations in usage:
Arrow functions don't have their own bindings to
this
,arguments
, orsuper
, and should not be used as methods.Arrow functions cannot be used as constructors. Calling them with
new
throws aTypeError
. They also don't have access to thenew.target
keyword.Arrow functions cannot use
yield
within their body and cannot be created as generator functions.
Lets see an example:
const arrow=()=>{
console.log("hello");
}
arrow();
Normal Function vs Arrow Function
- Syntax
//normal function
function addTwoNumbers1(a,b){
return (a+b);
}
//arrow function
const addTwoNumbers2=(a,b)=>{
return (a+b);
}
- Implicit Return
//you can rewrite the above arrow function like this but not with normal fn
const addTwoNumbers2=(a,b)=>(a+b)
- Arguments
//normal functions receive the arguments even without receiving them in the
//formal parameters but arrow functions cannot
function hello(){
console.log(arguments);
}
hello(4,5);
- This keyword
const user={
username:"Mainak",
rc1:()=>{
console.log(this.username);
},
rc2(){
console.log(this.username);
}
}
user.rc1();//this wont work and will return undefined since as per definition
//of arrow function it can't be used with this keyword
user.rc2();//normal function will work fine and will give the output
Wrapping Up
So thats it and thanks a lot for reading this far and I will meet you in the next part where we will demystify Closures , till then bye!