Javascript Interview Questions & Answers (Part 2)
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 6 console.log (numberArray); // returns [6] console.log (pureAddNumber (7) (numberArray)); // returns [6, 7] console.log (numberArray); // returns [6]
As per above code snippets, Push function is impure itself by altering the array and returning an push number index which is independent of 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 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 makes harder to break your application by not having any side effects. These principles are coming together with Immutability concept of ES6 by giving preference to const over let usage.
What is the purpose of let keyword?
The let statement declares a block scope local variable. Hence the variables defined with let keyword are limited in scope to the block, statement, or expression on which it is used. Whereas variables declared with the var keyword used to define a variable globally, or locally to an entire function regardless of block scope. Let’s take an example to demonstrate the usage,
let counter = 30; if (counter === 30) { let counter = 31; console.log(counter); // 31 } console.log(counter); // 30 (because if block variable won't exist here)
What is the reason to choose the name let as keyword?
Let is a mathematical statement that was adopted by early programming languages like Scheme and Basic. It has been borrowed from dozens of other languages that use let already as a traditional keyword as close to var as possible.
How do you redeclare variables in switch block without an error?
If you try to redeclare variables in a switch block then it will cause errors because there is only one block. For example, the below code block throws a syntax error as below,
let counter = 1; switch(x) { case 0: let name; break; case 1: let name; // SyntaxError for redeclaration. break; } To avoid this error, you can create a nested block inside a case clause will create a new block scoped lexical environment. let counter = 1; switch(x) { case 0: { let name; break; } case 1: { let name; // No SyntaxError for redeclaration. break; } }
What is Temporal Dead Zone?
The Temporal Dead Zone is a behavior in JavaScript that occurs when declaring a variable with the let and const keywords, but not with var. In ECMAScript 6, accessing a let or const variable before its declaration (within its scope) causes a ReferenceError. The time span when that happens, between the creation of a variable’s binding and its declaration, is called the temporal dead zone. Let’s see this behavior with an example,
function somemethod() { console.log(counter1); // undefined console.log(counter2); // ReferenceError var counter1 = 1; let counter2 = 2; }
What is IIFE(Immediately Invoked Function Expression)?
IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined. The signature of it would be as below,
(function () { // logic here } ) ();
The primary reason to use an IIFE is to obtain data privacy because any variables declared within the IIFE cannot be accessed by the outside world. i.e, If you try to access variables with IIFE then it throws an error as below,
(function () { var message = "IIFE"; console.log(message); } ) (); console.log(message); //Error: message is not defined
What is the benefit of using modules?
There are a lot of benefits to using modules in favour of a sprawling. Some of the benefits are,
Maintainablity
Reusability
Namespacing
What is memoization?
Memoization is a programming technique which attempts to increase a function’s performance by caching its previously computed results. Each time a memoized function is called, its parameters are used to index the cache. If the data is present, then it can be returned, without executing the entire function. Otherwise the function is executed and then the result is added to the cache. Let’s take an example of adding function with memorization,
const memoizAddition = () => { let cache = {}; return (value) => { if (value in cache) { console.log('Fetching from cache'); return cache[value]; // Here, cache.value cannot be used as property name starts with the number which is not valid JavaScript identifier. Hence, can only be accessed using the square bracket notation. } else { console.log('Calculating result'); let result = value + 20; cache[value] = result; return result; } } } // returned function from memoizAddition const addition = memoizAddition(); console.log(addition(20)); //output: 40 calculated console.log(addition(20)); //output: 40 cached
What are the main rules of promise?
A promise must follow a specific set of rules,
- A promise is an object that supplies a standard-compliant .then() method
- A pending promise may transition into either fulfilled or rejected state
- A fulfilled or rejected promise is settled and it must not transition into any other state.
- Once a promise is settled, the value must not change.
What is callback in callback?
You can nest one callback inside in another callback to execute the actions sequentially one by one. This is known as callbacks in callbacks.
loadScript('/script1.js', function(script) { console.log('first script is loaded'); loadScript('/script2.js', function(script) { console.log('second script is loaded'); loadScript('/script3.js', function(script) { console.log('third script is loaded'); // after all scripts are loaded }); }) });
What is Hoisting?
Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution. Remember that JavaScript only hoists declarations, not initialisation. Let’s take a simple example of variable hoisting,
console.log(message); //output : undefined var message = ’The variable Has been hoisted’;
The above code looks like as below to the interpreter,
var message; console.log(message); message = ’The variable Has been hoisted’;
What are classes in ES6?
In ES6, Javascript classes are primarily syntactical sugar over JavaScript’s existing prototype-based inheritance. For example, the prototype based inheritance written in function expression as below,
function Bike(model,color) { this.model = model; this.color = color; } Bike.prototype.getDetails = function() { return this.model+ ' bike has' + this.color+ ' color'; };
Whereas ES6 classes can be defined as an alternative
class Bike{ constructor(color, model) { this.color= color; this.model= model; } }
What are closures?
A closure is the combination of a function and the lexical environment within which that function was declared. i.e, It is an inner function that has access to the outer or enclosing function’s variables. The closure has three scope chains
- Own scope where variables defined between its curly brackets
- Outer function’s variables
- Global variables Let’s take an example of closure concept,
function Welcome(name){ var greetingInfo = function(message){ console.log(message+' '+name); } return greetingInfo; } var myFunction = Welcome('John'); myFunction('Welcome '); //Output: Welcome John myFunction('Hello Mr.'); //output: Hello Mr.John
As per the above code, the inner function(greetingInfo) has access to the variables in the outer function scope(Welcome) even after outer function has returned.
What are modules?
Modules refers small units of independent, reusable code and also act as foundation of many JavaScript design patterns. Most of the JavaScript modules export an object literal, a function, or a constructor
What is scope in javascript?
Scope is the accessibility of variables, functions, and objects in some particular part of your code during runtime. In other words, scope determines the visibility of variables and other resources in areas of your code.
What is a service worker?
A Service worker is basically a script (JavaScript file) that runs in background, separate from a web page and provide features that don’t need a web page or user interaction. Some of the major features of service workers are Rich offline experiences(offline first web application development), periodic background syncs, push notifications, intercept and handle network requests and programmatically managing a cache of responses.
How do you manipulate DOM using service worker?
Service worker can’t access the DOM directly. But it can communicate with the pages it controls by responding to messages sent via the postMessage interface, and those pages can manipulate the DOM.
How do you reuse information across service worker restarts?
The problem with service worker is that it get terminated when not in use, and restarted when it’s next needed, so you cannot rely on global state within a service worker’s onfetch and onmessage handlers. In this case, service workers will have access to IndexedDB API in order to persist and reuse across restarts.
What is IndexedDB?
IndexedDB is a low-level API for client-side storage of larger amounts of structured data, including files/blobs. This API uses indexes to enable high-performance searches of this data.
What is web storage?
Web storage is an API that provides a mechanism by which browsers can store key/value pairs locally within the user’s browser, in a much more intuitive fashion than using cookies. The web storage provides two mechanisms for storing data on the client.
Local storage: It stores data for current origin with no expiration date.
Session storage: It stores data for one session and the data is lost when the browser tab is closed.
What is a post message?
Post message is a method that enables cross-origin communication between Window objects.(i.e, between a page and a pop-up that it spawned, or between a page and an iframe embedded within it). Generally, scripts on different pages are allowed to access each other if and only if the pages follow same-origin policy(i.e, pages share the same protocol, port number, and host).
What is promise chaining?
The process of executing a sequence of asynchronous tasks one after another using promises is known as Promise chaining. Let’s take an example of promise chaining for calculating the final result,
new Promise(function(resolve, reject) { setTimeout(() => resolve(1), 1000); }).then(function(result) { console.log(result); // 1 return result * 2; }).then(function(result) { console.log(result); // 2 return result * 3; }).then(function(result) { console.log(result); // 6 return result * 4; });
In the above handlers, the result is passed to the chain of .then() handlers with the below work flow,
- The initial promise resolves in 1 second,
- After that .then handler is called by logging the result(1) and then return a promise with the value of result *
- After that the value passed to the next .then handler by logging the result(2) and return a promise with result *
- Finally the value passed to the last .then handler by logging the result(6) and return a promise with result *
What is promise.all?
Promise.all is a promise that takes an array of promises as an input (an iterable), and it gets resolved when all the promises get resolved or any one of them gets rejected. For example, the syntax of promise.all method is below,
Promise.all([Promise1, Promise2, Promise3]).then(result) => { console.log(result) }).catch(error => console.log(`Error in promises ${error}`))
Note: Remember that the order of the promises(output the result) is maintained as per input order.