Today we will see a frequently asked Javascript interview question.
The question goes like this:
Implement a
product
method that will return the product of two numbers when invoked using any of the following two ways
- product(4, 5)
- product(4)(5)
This is a very famous Javascript interview question because it tests your knowledge of functional Javascript, closures, and function arguments. To solve this, let’s understand some basic concepts.
Higher order function
A higher order function is a function which either accepts a function, returns a function or both.
For Example: Array map, filter, reduce methods all accept a function as an argument and are higher order functions.
When a function returns another function it’s also called a higher order function.
function greet(message) {
return function(name) {
console.log(message, name);
};
}
const hello = greet('Hello');
console.log(hello('Mark')); // Hello Mark
Here, instead of creating a separate variable to store the result of greet function, we can directly call it like this:
console.log(greet('Hello')('Mark')); // Hello Mark
arguments Object
Every function we write has access to the arguments object which contains the list of values passed while calling the function:
function add() {
let sum = 0;
for(let i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
console.log(sum); // 15
}
add(1, 2, 3, 4, 5);
Note: arrow functions do not have access to the arguments object.
So using this higher order function and arguments
object, we can implement the product
method in the following two ways.
- By counting arguments length:
function product(a) {
if (arguments.length == 2) {
return arguments[0] * arguments[1];
} else {
return function(b) {
return a * b;
};
}
}
console.log(product(4, 5)); // 20
console.log(product(4)(5)); // 20
- By checking if the second argument exists:
function product(a, b) {
if (b) { // if b exists
return a * b;
} else {
return function(b) {
return a * b;
};
}
}
console.log(product(4, 5)); // 20
console.log(product(4)(5)); // 20
There is one issue in the second approach. In javascript, 0 is considered as a falsy
value.
So we get different output if we call the function as shown below:
console.log(product(4, 0)); // function (b) {}
console.log(product(4)(0)); // 0
So to fix that, we can re-write the above function as
function product(a, b) {
if (b || b === 0) { // if b exists or b is zero
return a * b;
} else {
return function(b) {
return a * b;
};
}
}
console.log(product(4, 0)); // 0
console.log(product(4)(0)); // 0
console.log(product(4, 5)); // 20
console.log(product(4)(5)); // 20
You can add extra validation also inside the function to check if the values passed to function are numbers and only then return product else return some generic error message like “input is not valid”
Thanks for reading!
Want to learn all ES6+ features in detail including let and const, promises, various promise methods, array and object destructuring, arrow functions, async/await, import and export and a whole lot more from scratch?
Check out my Mastering Modern JavaScript book. This book covers all the pre-requisites for learning React and helps you to become better at JavaScript and React.
Check out free preview contents of the book here.
Also, you can check out my free Introduction to React Router course to learn React Router from scratch.
Want to stay up to date with regular content regarding JavaScript, React, Node.js? Follow me on LinkedIn.