We have collected from our sources those are attended realtime frontend developer or web developer or fullstack developer interviews and updated list of javascript interview questions and answers accordingly. Please go through and add your feedback in comments if you have experienced other questions. We will update accordingly, it will help others who are preparing for interviews.
Basic Questions
1. What is closure in javascript? Give an example.
A closure is the combination of a function and the lexical environment within which that function was declared. In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.
To use a closure, simply define a function inside another function and expose it. To expose a function, return it or pass it to another function.
The inner function will have access to the variables in the outer function scope, even after the outer function has returned.
In this example, each call to the main function creates a separate closure
function newClosure(someNum, someRef) {
// Local variables that end up within closure
var num = someNum;
var anArray = [1,2,3];
var ref = someRef;
return function(x) {
num += x;
anArray.push(num);
console.log('num: ' + num +
'; anArray: ' + anArray.toString() +
'; ref.someVar: ' + ref.someVar + ';');
}
}
obj = {someVar: 4};
fn1 = newClosure(4, obj);
fn2 = newClosure(5, obj);
fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;
fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;
obj.someVar++;
fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;
fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;
References :
2. Explain OOPS concepts in javascript?
Object-oriented programming (OOP) is a programming paradigm that uses abstraction to create models based on the real world. OOP uses several techniques from previously established paradigms, including modularity, polymorphism, and encapsulation.
Terminology
- Namespace – A container which lets developers bundle all functionality under a unique, application-specific name.
- Class – Defines the object’s characteristics. A class is a template definition of an object’s properties and methods.
- Object – An instance of a class.
- Property – An object characteristic, such as color.
- Method – An object capability, such as walk. It is a subroutine or function associated with a class.
- Constructor – A method called at the moment an object is instantiated. It usually has the same name as the class containing it.
- Inheritance – A class can inherit characteristics from another class.
- Encapsulation – A method of bundling the data and methods that use the data.
- Abstraction – The conjunction of an object’s complex inheritance, methods, and properties must adequately reflect a reality model.
- Polymorphism – Poly means “many” and morphism means “forms”. Different classes might define the same method or property.
Prototype-based programming
Prototype-based programming is an OOP model that doesn’t use classes, but rather it first accomplishes the behavior of any class and then reuses it (equivalent to inheritance in class-based languages) by decorating (or expanding upon) existing prototype objects. (Also called classless, prototype-oriented, or instance-based programming.)
The class
JavaScript is a prototype-based language and contains no class statement, such as is found in C++ or Java. This is sometimes confusing for programmers accustomed to languages with a class statement. Instead, JavaScript uses functions as constructors for classes. Defining a class is as easy as defining a function. In the example below we define a new class called Person with an empty constructor.
var Person = function () {};
The object (class instance)
To create a new instance of an object obj we use the statement new obj, assigning the result (which is of type obj) to a variable to access it later.
var person1 = new Person();
The constructor
The constructor is called at the moment of instantiation (the moment when the object instance is created). The constructor is a method of the class. In JavaScript the function serves as the constructor of the object, therefore there is no need to explicitly define a constructor method. Every action declared in the class gets executed at the time of instantiation.
Check full article about OOPS concepts here :
3. Explain about Array Prototype?
The Array.prototype property represents the prototype for the Array constructor and allows you to add new properties and methods to all Array objects.
Array instances inherit from Array.prototype. As with all constructors, you can change the constructor’s prototype object to make changes to all Array instances.
if (!Array.prototype.first) {
Array.prototype.first = function() {
return this[0];
}
}
Array.isArray(Array.prototype); // true
Array.prototype itself is an Array.
Note: Array.prototype does not refer to a single array, but to the Array() object itself.
Note: Prototype is a global object constructor which is available for all JavaScript objects.
References :
4.What is an Object in JS?
An instance of class. An object is a collection of properties, and a property is an association between a name (or key) and a value. A property’s value can be a function, in which case the property is known as a method.
var myCar = new Object();
myCar.make = 'Ford';
References :
5. What is a defered object in JS?
The Deferred object, introduced in jQuery 1.5, is a chainable utility object created by calling the jQuery.Deferred() method. It can register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.
The Deferred object is chainable, similar to the way a jQuery object is chainable, but it has its own methods. After creating a Deferred object, you can use any of the methods below by either chaining directly from the object creation or saving the object in a variable and invoking one or more methods on that variable.
According to our requirements and the list of methods provided, it’s clear than we can use either the done() or the then() method to manage the successful cases. Since many of you might already be accustomed to the JavaScript’s Promise object, in this example I’ll employ the then() method. One important difference between these two methods is that then() has the ability to forward the value received as a parameter to other then(), done(), fail(), or progress() calls defined after it.
function timeout(milliseconds) {
// Create a new Deferred object
var deferred = $.Deferred();
// Resolve the Deferred after the amount of time specified by milliseconds
setTimeout(deferred.resolve, milliseconds);
// Return the Deferred's Promise object
return deferred.promise();
}
timeout(1000).then(function() {
console.log('I waited for 1 second!');
});
deferred.always()
Add handlers to be called when the Deferred object is either resolved or rejected.deferred.catch()
Add handlers to be called when the Deferred object is rejected.deferred.done()
Add handlers to be called when the Deferred object is resolved.deferred.fail()
Add handlers to be called when the Deferred object is rejected.deferred.notify()
Call the progressCallbacks on a Deferred object with the given args.deferred.notifyWith()
Call the progressCallbacks on a Deferred object with the given context and args.deferred.pipe()
Utility method to filter and/or chain Deferreds.deferred.progress()
Add handlers to be called when the Deferred object generates progress notifications.deferred.promise()
Return a Deferred’s Promise object.deferred.reject()
Reject a Deferred object and call any failCallbacks with the given args.deferred.rejectWith()
Reject a Deferred object and call any failCallbacks with the given context and args.deferred.resolve()
Resolve a Deferred object and call any doneCallbacks with the given args.deferred.resolveWith()
Resolve a Deferred object and call any doneCallbacks with the given context and args.deferred.state()
Determine the current state of a Deferred object.deferred.then()
Add handlers to be called when the Deferred object is resolved, rejected, or still in progress.jQuery.Deferred()
A factory function that returns a chainable utility object with methods to register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.jQuery.when()
Provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events..promise()
Return a Promise object to observe when all actions of a certain type bound to the collection, queued or not, have finished.
References :
- https://api.jquery.com/category/deferred-object/
- https://www.sitepoint.com/introduction-jquery-deferred-objects/
- https://www.sitepoint.com/overview-javascript-promises/
6. How to make a http external api call and display data?
We can make api call in lot of ways. Here i’m gonna give example using jQuery’s $.ajax function.
Using $.ajax ==>
$.ajax({
url: 'users.php',
dataType: 'json',
type: 'post',
contentType: 'application/json',
data: JSON.stringify( { "first-name": $('#first-name').val(), "last-name": $('#last-name').val() } ),
processData: false,
success: function( data, textStatus, jQxhr ){
$('#response pre').html( JSON.stringify( data ) );
},
error: function( jqXhr, textStatus, errorThrown ){
console.log( errorThrown );
}
});
7. In JS, Is multiple thread possible or not?
JavaScript is single-threaded in the same context, but browser Web APIs are not. Also we have possibility of simulating parallelism by using setTimeout function or, with some limitations, by the use of the real parallelism provided by WebWorkers.
Your JavaScript code is single-threaded in the same context, but all other stuff which is done by browser (AJAX request, rendering, event triggers etc.) is not. Even Google Chrome will not let a single web page’s JavaScript run concurrently because this would cause massive concurrency issues in existing web pages. All Chrome does is separate multiple components (different tabs, plug-ins, etcetera) into separate processes, but I can’t imagine a single page having more than one JavaScript thread.
Note : Dedicated Web Workers provide a simple means for web content to run scripts in background threads. Once created, a worker can send messages to the spawning task by posting messages to an event handler specified by the creator.
References :
8. Explain timeout concept in JS and why do we need it?
The setTimeout() method calls a function or evaluates an expression after a specified number of milliseconds.
Because by calling long-executing code via setTimeout, you actually create 2 events: setTimeout execution itself, and (due to 0 timeout), separate queue entry for the code being executed.
var myVar;
function myFunction() {
myVar = setTimeout(function(){ alert("Hello") }, 3000);
}
function myStopFunction() {
clearTimeout(myVar);
}
References :
9. What is Promises? How do you achieve? What are the pros and cons of using Promises instead of callbacks?
A Promise object represents a value that may not be available yet, but will be resolved at some point in the future. It allows you to write asynchronous code in a more synchronous fashion.
It will be in one of 3 possible states:
- Fulfilled: onFulfilled() will be called (e.g., resolve() was called)
- Rejected: onRejected() will be called (e.g., reject() was called)
- Pending: not yet fulfilled or rejected
A promise is settled if it’s not pending (it has been resolved or rejected). Sometimes people use resolved and settled to mean the same thing: not pending. Once settled, a promise can not be resettled. Calling resolve() or reject() again will have no effect. The immutability of a settled promise is an important feature.
We start by instantiating a new Promise object and passing it a callback function. The callback takes two arguments, resolve and reject, which are both functions. All your asynchronous code goes inside that callback. If everything is successful, the promise is fulfilled by calling resolve(). In case of an error, reject() is called with an Error object. This indicates that the promise is rejected.
Example:
function getPromise(url){
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest();
request.open("GET", url);
request.onload = () => {
if (request.status === 200) {
resolve(request.response);
} else {
reject(Error(request.statusText));
}
};
request.onerror = () => {
reject(Error("Error fetching data."));
};
request.send();
});
}
const promise = getPromise("https://api.github.com/users/gopigoppu");
console.log("Asynchronous request made.");
promise.then( result => {
console.log("Got data! Promise fulfilled.");
console.log(JSON.parse(result).followers_url);
//we have our result here
return getPromise(JSON.parse(result).followers_url); //return a promise here again
}).then(
data => {
console.log("Got data! Promise fulfilled.", data);
document.body.textContent = data;
}).catch(function(err) {
console.log("It failed!", err);
});
References :
10. Node.js is single threaded or multi threaded?
All Node JS applications uses “Single Threaded Event Loop Model” architecture to handle multiple concurrent clients. So Yes NodeJS is single threaded, but this is a half truth, actually it is event-driven and single-threaded with background workers. The main event loop is single-threaded but most of the I/O works run on separate threads, because the I/O APIs in Node.js are asynchronous/non-blocking by design, in order to accommodate the event loop.
Node.js was created explicitly as an experiment in async processing. The theory was that doing async processing on a single thread could provide more performance and scalability under typical web loads than the typical thread-based implementation.
References:
11. What is Higher Order Functions?
Functions that operate on other functions, either by taking them as arguments or by returning them, are called higher-order functions.
The “higher-order” concept can be applied to functions in general, like functions in the mathematical sense.
// Return function from function
//array of names to be used in the function
const names= ['John', 'Tina','Kale','Max']
//Function returning secondFunction()
function returnFunction(arr) {
//returnFunction() returns the secondFunction() which needs the argument y
return function secondFunction(y) {
console.log("First argument is an array: "+ arr);
console.log("Argument passed to secondFunction is "+ y );
};
}
//secondFunction() is assigned to myFunc
const myFunc = returnFunction(names);
//"a string." is passed as the y variable to secondFunction()
myFunc("a string.");
/*Result printed:
First argument is an array: John,Tina,Kale,Max.
Argument passed to secondFunction is a string.
*/
//You can also pass both variables as below.
returnFunction(names)("a string.");
function greaterThan(n) {
return m => m > n;
}
let greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
// → true
Built-in higher-order functions in JavaScript
Many of the built-in JavaScript functions on arrays, strings, DOM methods, promise methods, etc. are higher-order functions that provide a significant level of abstraction.
Listed below are a few of the many built-in higher-order functions:
- Array.prototype.map()
- Array.prototype.filter()
- Array.prototype.reduce()
- Array.prototype.forEach()
- EventTarget.addEventListener()
Benefits of higher-order functions
- They are an excellent way to abstract and separate actions in a program.
- They are easy to reuse.
- They provide simplicity to the code, allowing the programmer and any other party to understand the code at a high level easily.
- They make it less time-consuming to write fully functioning and clear code as it’s easier to debug when higher-order functions are used.
- Also, they help write compressed and composed code when programs get more complex.
12. What is Function currying?
It is a technique in functional programming, transformation of the function of multiple arguments into several functions of a single argument in sequence.
The translation of function happens something like this,
function simpleFunction(param1, param2, param3, …..) => function curriedFunction(param1)(param2)(param3)(….
Currying is when you break down a function that takes multiple arguments into a series of functions that each take only one argument. Here’s an example in
// This is a function that takes one argument, a,
// and returns a function that takes another argument, b,
// and that function returns their sum.
function add (a) {
return function (b) {
return a + b;
}
}
add(3)(4);
var add3 = add(3);
add3(4);
13. what is De-bouncing technique in javascript?
Debouncing is a programming pattern or a technique to restrict the calling of a time-consuming function frequently, by delaying the execution of the function until a specified time to avoid unnecessary CPU cycles, and API calls and improve performance.
Debouncing is a method used in JavaScript to increase browser performance. There may be some features on a web page that needs time-consuming computations. If such a feature of functionality is invoked frequently, it might greatly affect the performance of the browser, as JavaScript is a single threaded language. Here Debouncing comes into picture like said above.
function debounce(func, timeout = 300){
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => { func.apply(this, args); }, timeout);
};
}
function saveInput(){
console.log('Saving data');
}
const processChange = debounce(() => saveInput());
When a visitor writes the first letter and releases the key, the debounce
first resets the timer with clearTimeout(timer)
. At this point, the step is not necessary as there is nothing scheduled yet. Then it schedules the provided function—saveInput()
—to be invoked in 300 ms.
But let’s say that the visitor keeps writing, so each key release triggers the debounce
again. Every invocation needs to reset the timer, or, in other words, cancel the previous plans with saveInput()
, and reschedule it for a new time—300 ms in the future. This goes on as long as the visitor keeps hitting the keys under 300 ms.
The last schedule won’t get cleared, so the saveInput()
will finally be called.
14. Explain advantages and disadvantages of Server Side Rendering (SSR) over Client Side Rendering (CSR)?
Server Side Rendering (SSR)
Server Side Rendering means generating the HTML for a webpage on the server side. In Server Side Rendering (SSR) the HTML components of the webpage are generated on the server-side. When a browser requests a SSR web page, the browser receives a fully formed HTML web page with the HTML components already created. SSR is very popular among React and Angular frameworks as they provide some pretty neat integration methods.
Client Side Rendering (CSR)
Client Side Rendering means generating the HTML components on the browser side, by executing Javascript code within the browser that manipulates the HTML DOM to build the HTML nodes. This is done using the Javascript framework that compiles and generates code at the browser-end. CSR can be incorporated with the help of Javascript frameworks and libraries like Angular, VueJS and React SSR.
CSR vs SSR
15. Explain differences between DOM, V-DOM and Shadow DOM?
Document Object Model (DOM)
DOM (Document Object Model) is an Application Programming Interface (API) that curates a specific structure of XML and HTML documents that can be easily controlled and accessed.
It’s a way of representing a structured document via objects. It is cross-platform and language-independent convention for representing and interacting with data in HTML, XML, and others. Web browsers handle the DOM implementation details, so we can interact with it using JavaScript and CSS.
Virtual DOM:
- Virtual DOM, in simple terms, is nothing but the complete and full representation of an actual DOM.
- Virtual DOM is a concept of DOM used by React.js and Vue.js.
- In Virtual DOM concept copy of DOM is saved in the memory and while any change is done in the DOM, it’s compared to find differences.
- Then browser knows which elements were changed and can update only those part of the application to avoid re-rendering all the DOM. It’s done to improve the performance of the UI libraries.
Shadow DOM:
- Shadow DOM, on the other hand, relates mostly to the concept of encapsulation. It is a tool that allows developers to overcome DOM encapsulation.
- Shadow DOM comes in small pieces, and it doesn’t represent the whole Document Object Model. We can see it as a subtree or as a separate DOM for an element.
- In the case of Shadow DOM, we create a scoped tree, which is connected to the element but separated from the children elements. It’s called shadow tree and the element it’s attached to is called shadow host. And here we come to a great advantage of the Shadow DOM, everything which we will add to Shadow DOM is local, even styles
Differences between Shadow DOM and Virtual DOM
The only thing which is common for both is that they help with performance issues. Both create a separate instance of the Document Object Model; besides this, both concepts are different. Virtual DOM is creating a copy of the whole DOM object, and Shadow DOM creates small pieces of the DOM object which has their own, isolated scope for the element they represent.
Virtual DOM | Shadow DOM |
---|---|
It revolves around solving performance issues. | It revolves around the concept of encapsulation. |
It is a complete representation of an actual DOM. | It is not a complete representation of the entire DOM. |
It groups together several changes and does a single re-render instead of many small ones. | It adds a subtree of DOM elements into the rendering of a document, instead of adding it to the main document’s DOM tree. |
It creates a copy of the whole DOM object. | It creates small pieces of the DOM object having their own, isolated scope. |
It does not isolate the DOM. | It isolates the DOM. |
It does not help with CSS scoping. | It helps with CSS scoping. |
16. Explain ES6 concepts — Scope, Destructuring, spread and rest operators, WeakSet?
Scope
When declaring any variable in JavaScript, we used the var keyword. Var is a function scoped keyword. Within a function, we can access the variable. When we need to create a new scope, we wrap the code in a function.
Both let and const have block scope. If you use these keywords to declare a variable, it will only exist within the innermost block that surrounds them. If you declare a variable with let inside a block (for example, if a condition or a for-loop), it can only be accessed within that block.
The variables declared with the let keyword are mutable, which means that their values can be changed. It’s akin to the var keyword, but with the added benefit of block scoping. The variables declared with the const keyword are block-scoped and immutable. When variables are declared with the const keyword, their value cannot be modified or reassigned.
Destructuring
JavaScript Object Destructuring is the syntax for extracting values from an object property and assigning them to a variable. The destructuring is also possible for JavaScript Arrays.
Destructuring was introduced in ES6 as a way to extract data from arrays and objects into a single variable. It is possible to extract smaller fragments from objects and arrays using this method. The following is an example.
const user = {
'name': 'Alex',
'address': '15th Park Avenue',
'age': 43
}
const { name, age, salary=123455 } = user;
console.log(name, age, salary); // Output, Alex 43 123455
Spread operators
A string is an iterable type, and in an array, the spread operator transfers each character of an iterable to one element. As a result, each character in a string becomes an Array element.
The Spread Syntax is another excellent feature of ES6. As the name indicates, it takes an iterable (like an array) and expands (spreads) it into individual elements.
We can also expand objects using the spread syntax and copy its enumerable
properties to a new object.
Spread syntax helps us clone an object with the most straightforward syntax using the curly braces and three dots {...}
.
const user = {
'name': 'Alex',
'address': '15th Park Avenue',
'age': 43
}
const clone = {...user} // Output, {name: "Alex", address: "15th Park Avenue", age: 43}
clone === user; // Output, false
[...'apple']
// Output: ['a', 'p', 'p', 'l', 'e']
rest operators
The Rest
parameter is kind of opposite to the spread
syntax. While spread syntax helps expand or spread elements and properties, the rest parameter helps collect them together.
In the case of objects, the rest parameter is mostly used with destructuring syntax to consolidate the remaining properties in a new object you’re working with.
function restTest(one, two, ...args) {
console.log(one)
console.log(two)
console.log(args)
}
restTest(1, 2, 3, 4, 5, 6)
// Output
// 1
// 2
// [3, 4, 5, 6]
WeakSet
The WeakSet
object lets you store weakly held objects in a collection.
WeakSet
objects are collections of objects. Just as with Set
s, each object in a WeakSet
may occur only once; all objects in a WeakSet
‘s collection are unique.
The main differences to the Set
object are:
WeakSet
s are collections of objects only. They cannot contain arbitrary values of any type, asSet
s can.- The
WeakSet
is weak, meaning references to objects in aWeakSet
are held weakly. If no other references to an object stored in theWeakSet
exist, those objects can be garbage collected.
// Execute a callback on everything stored inside an object
function execRecursively(fn, subject, _refs = new WeakSet()) {
// Avoid infinite recursion
if (_refs.has(subject)) {
return;
}
fn(subject);
if (typeof subject === "object") {
_refs.add(subject);
for (const key in subject) {
execRecursively(fn, subject[key], _refs);
}
}
}
const foo = {
foo: "Foo",
bar: {
bar: "Bar",
},
};
foo.bar.baz = foo; // Circular reference!
execRecursively((obj) => console.log(obj), foo);
17. Difference between the regular functions and arrow functions with examples and use case?
18. What is Webpack and babel?
Medium Question
1. What is event looping?
The Event Loop is a queue of callback functions. When an async function executes, the callback function is pushed into the queue. The JavaScript engine doesn’t start processing the event loop until the code after an async function has executed.
Reference :
2. What are all testing tool using in javascript?
- Unit TestingUnit testing is the practice of testing small pieces of code, typically individual functions, alone and isolated. If your test uses some external resource, like the network or a database, it’s not a unit test.Popular tools for unit testing include Mocha, Jasmine and Tape.
- Integration TestingAs the name suggests, in integration testing the idea is to test how parts of the system work together – the integration of the parts. Integration tests are similar to unit tests, but there’s one big difference: while unit tests are isolated from other components, integration tests are not. For example, a unit test for database access code would not talk to a real database, but an integration test would.Integration tests can usually be written with the same tools as unit tests.
- Functional TestingFunctional testing is also sometimes called E2E testing, or browser testing. They all refer to the same thing.Functional testing is defined as the testing of complete functionality of some application. In practice with web apps, this means using some tool to automate a browser, which is then used to click around on the pages to test the application. Test tools can be divided into the following functionalities. Some provide us with only one functionality, and some provide us with a combination.The most common tool used for functional testing is Selenium. Running Selenium is usually done with Selenium WebDriver, or Protractor. Sometimes PhantomJS and CasperJS can be used as well, especially if you don’t need to test in real browsers.
In order to get a more flexible functionality, it’s common to use a combination of tools even if one can achieve relatively the same.
- Provide a testing structure (Mocha, Jasmine, Jest, Cucumber)
- Provide assertions functions (Chai, Jasmine, Jest, Unexpected)
- Generate, display, and watch test results (Mocha, Jasmine, Jest, Karma)
- Generate and compare snapshots of component and data structures to make sure changes from previous runs are intended (Jest, Ava)
- Provide mocks, spies, and stubs (Sinon, Jasmine, enzyme, Jest, testdouble)
- Generate code coverage reports (Istanbul, Jest, Blanket)
- Provide a browser or browser-like environment with a control on their scenarios execution (Protractor, Nightwatch, Phantom, Casper)
References :
3. Difference between timeout and interval? Write syntax for both?
- setTimeout(function, milliseconds) – Executes a function, after waiting a specified number of milliseconds.
- setInterval(function, milliseconds) – Same as setTimeout(), but repeats the execution of the function continuously.
- clearTimeout() method stops the execution of the function specified in.
Note : The setTimeout() and setInterval() are both methods of the HTML DOM Window object.
function myTimer() {
var d = new Date();
document.getElementById("demo").innerHTML = d.toLocaleTimeString();
}
var myVar1 = setTimeout(myTimer, milliseconds);
clearTimeout(myVar1);
var myVar2 = setInterval(myTimer, 1000);
clearInterval(myVar2);
References :
4. What is Class in JS? How do you intiantiate?
JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical sugar over JavaScript’s existing prototype-based inheritance. The class syntax does not introduce a new object-oriented inheritance model to JavaScript.
Classes are in fact “special functions”, and just as you can define function expressions and function declarations, the class syntax has two components: class expressions and class declarations.
The bodies of class declarations and class expressions are executed in strict mode i.e. constructor, static and prototype methods, getter and setter functions are executed in strict mode.
The constructor method is a special method for creating and initializing an object created with a class. There can only be one special method with the name “constructor” in a class. A SyntaxError will be thrown if the class contains more than one occurrence of a constructor method.
The static keyword defines a static method for a class. Static methods are called without instantiating their class and cannot be called through a class instance. Static methods are often used to create utility functions for an application.
function Animal (name) {
this.name = name;
}
Animal.prototype.speak = function () {
console.log(this.name + ' makes a noise.');
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
var d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
References :
5. What is Node.js? Explain Node.js features? Why we use Node.js specifically?
Node.js is an application runtime environment that allows you to write server-side applications in JavaScript.
Node.js favors asynchronous APIs because it is single-threaded. This allows it to efficiently manage its own resources, but requires that long-running operations be non-blocking, and asynchronous APIs are a way to allow for control of flow with lots of non-blocking operations.
Features :
- Node.js is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
- its unique I/O model, it excels at the sort of scalable and real-time situations we are increasingly demanding of our servers.
- It’s also lightweight, efficient, and its ability to use JavaScript on both frontend and backend opens new avenues for development.
- Node.js’ package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
Pros:
- If your application doesn’t have any CPU intensive computation, you can build it in Javascript top-to-bottom, even down to the database level if you use JSON storage Object DB like MongoDB. This eases development (including hiring) significantly.
- Crawlers receive a fully-rendered HTML response, which is far more SEO-friendly than, say, a Single Page Application or a websockets app run on top of Node.js.
Cons:
- Any CPU intensive computation will block Node.js responsiveness, so a threaded platform is a better approach. Alternatively, you could try scaling out the computation [*].
- Using Node.js with a relational database is still quite a pain (see below for more detail). Do yourself a favour and pick up any other environment like Rails, Django, or ASP.Net MVC if you’re trying to perform relational operations
References :
6. What is callback?
A callback function, also known as a higher-order function. 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.
A callback function is essentially a pattern (an established solution to a common problem), and therefore, the use of a callback function is also known as a callback pattern.
function greeting(name) {
alert('Hello ' + name);
}
function processUserInput(callback) {
var name = prompt('Please enter your name.');
callback(name);
}
processUserInput(greeting);
References :
7. What is callback hell?
Callback hell is any code where the use of function callbacks in async code becomes obscure or difficult to follow. Generally, when there is more than one level of indirection, code using callbacks can become harder to follow, harder to refactor, and harder to test. A code smell is multiple levels of indentation due to passing multiple layers of function literals.
If you have lots of behavioural dependencies in your code like this, it can get troublesome fast. Especially if it branches…
a({
parameter : someParameter,
callback : function(status) {
if (status == states.SUCCESS) {
b(function(status) {
if (status == states.SUCCESS) {
c(function(status){
if (status == states.SUCCESS) {
// Not an exaggeration. I have seen
// code that looks like this regularly.
}
});
}
});
} elseif (status == states.PENDING {
...
}
}
});
You can avoid callback hell problem in lot of ways. Famous one is using Promises.
References :
8. What is async function?
The async
function declaration defines an asynchronous function, which returns an AsyncFunction object.
An async function can contain an await expression that pauses the execution of the async function and waits for the passed Promise’s resolution, and then resumes the async function’s execution and returns the resolved value.
Remember, the await keyword is only valid inside async functions. If you use it outside of an async function’s body, you will get a SyntaxError.
async function getProcessedData(url) {
let v;
try {
v = await downloadData(url);
} catch(e) {
v = await downloadFallbackData(url);
}
return processDataInWorker(v);
}
References :
9. Explain about prototype inheritance in javascript?
JavaScript is a prototype-based language, meaning object properties and methods can be shared through generalized objects that have the ability to be cloned and extended. This is known as prototypical inheritance and differs from class inheritance.
Every object in JavaScript has an internal property called [[Prototype]]
.
Note : The double square brackets that enclose [[Prototype]]
signify that it is an internal property, and cannot be accessed directly in code.
Another way to find the [[Prototype]]
is through the __proto__
property. __proto__
is a property that exposes the internal [[Prototype]]
of an object.
Note : It is important to note that .__proto__
is a legacy feature and should not be used in production code, and it is not present in every modern browser.
let x = {};
// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, …}
Object.getPrototypeOf(x);
// output will be the same as if you had used getPrototypeOf().
// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, …}
x.__proto__;
It is important that every object in JavaScript has a [[Prototype]]
as it creates a way for any two or more objects to be linked.
Prototype Inheritance :
When you attempt to access a property or method of an object, JavaScript will first search on the object itself, and if it is not found, it will search the object’s [[Prototype]]. If after consulting both the object and its [[Prototype]] still no match is found, JavaScript will check the prototype of the linked object, and continue searching until the end of the prototype chain is reached.
At the end of the prototype chain is Object.prototype. All objects inherit the properties and methods of Object. Any attempt to search beyond the end of the chain results in null.
let y = [];
y.__proto__ === Array.prototype; // true
y.__proto__.__proto__ === Object.prototype; // true
y instanceof Array; // true
References :
10. What is the difference between Array.splice() and Array.slice()?
Array.splice()
The splice() method adds/removes items to/from an array, and returns the removed item(s).
Syntax :
array.splice(index, howmany, item1, ....., itemX)
var fruits = ["Banana", "Orange", "Apple", "Mango"];
// Banana,Orange,Lemon,Kiwi,Mango
fruits.splice(2, 1, "Lemon", "Kiwi");
Array.slice()
The slice() method returns the selected elements in an array, as a new array object. The slice() method selects the elements starting at the given start argument, and ends at, but does not include, the given end argument.
Syntax :
array.slice(start, end)
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
// Orange,Lemon
var citrus = fruits.slice(1, 3);
References :
11. What is the difference between .bind() , .call() and .apply()?
Use .bind() when you want that function to later be called with a certain context, useful in events.
Use .call() or .apply() when you want to invoke the function immediately, and modify the context.
They all attach this into function (or object) and the difference is in the function invocation (see below).
- call attaches
this
into function and executes the function immediately
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
// expected output: "cheese"
console.log(new Food('cheese', 5).name);
apply
is similar tocall
except that it takes an array-like object instead of listing the arguments out one at a time
function personContainer() {
var person = {
name: "James Smith",
hello: function() {
console.log(this.name + " says hello " + arguments[1]);
}
}
person.hello.apply(person, arguments);
}
personContainer("world", "mars");
// output: "James Smith says hello mars", note: arguments[0] = "world" , arguments[1] = "mars"
- bind attaches
this
into function and it needs to be invoked separately like this
var person = {
name: "James Smith",
hello: function(thing) {
console.log(this.name + " says hello " + thing);
}
}
person.hello("world"); // output: "James Smith says hello world"
var helloFunc = person.hello.bind({ name: "Jim Smith" });
helloFunc("world"); // output: Jim Smith says hello world"
References :
- https://stackoverflow.com/a/31922712
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
12. Explain about javascript hoisting?
Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.
JavaScript Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables or classes to the top of their scope, prior to execution of the code.
Hoisting allows functions to be safely used in code before they are declared.
Variable hoisting
Variable hoisting will be identified as two part of scoped variables.
- Global scoped variables
- var – either the enclosing function or for variables declared outside any function, global.
console.log(hoist); // Output: undefined
var hoist = 'The variable has been hoisted.';
- Function scoped variables
- let – is a block scoped and not function scoped
- const – variables whose value cannot be modified once assigned.
console.log(num); // Throws ReferenceError exception as the variable value is uninitialized
let num = 6; // Initialization
console.log(hoist); // Output: ReferenceError: hoist is not defined
const hoist = 'The variable has been hoisted.';
const PI = 3.142;
PI = 22/7; // Let's reassign the value of PI
console.log(PI); // Output: TypeError: Assignment to constant variable.
Hoisting functions
JavaScript functions can be loosely classified as the following:
- Function declarations – These are of the following form and are hoisted completely to the top.
- Function expressions – expressions are not evaluated until the relevant line is executed.
hoisted(); // Output: "This function has been hoisted."
function hoisted() {
console.log('This function has been hoisted.');
};
expression(); // Output: TypeError: expression is not a function
var expression = function hoisting() {
console.log('Will this work?');
};
Hoisting classes
JavaScript classes too can be loosely classified either as:
- Class declarations – JavaScript class declarations are hoisted. However, they remain uninitialised until evaluation. This effectively means that you have to declare a class before you can use it.
- Class expressions – class expressions are not hoisted, until the relevant line is executed.
// Class declarations example
var Frodo = new Hobbit();
Frodo.height = 100;
Frodo.weight = 300;
console.log(Frodo); // Output: ReferenceError: Hobbit is not defined
class Hobbit {
constructor(height, weight) {
this.height = height;
this.weight = weight;
}
}
// Class Expressions example
var Square = new Polygon();
Square.height = 10;
Square.width = 10;
console.log(Square); // Output: TypeError: Polygon is not a constructor
var Polygon = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
References :
13. How to make a deep copy in javascript?
Javascript :
var newObject = JSON.parse(JSON.stringify(oldObject));
Note: Beware using the JSON.parse(JSON.stringify(obj)) method on Date objects – JSON.stringify(new Date()) returns a string representation of the date in ISO format, which JSON.parse() doesn’t convert back to a Date object. See this answer for more details.
So, The Date object’s constructor can take a date string, so you can turn those string values back into dates by doing:
var x = new Date(JSON.parse(JSON.stringify(new Date())));
Additionally, please note that, in Chrome 65 at least, native cloning is not the way to go. According to this JSPerf, performing native cloning by creating a new function is nearly 800x slower than using JSON.stringify which is incredibly fast all the way across the board
jQuery :
// Shallow copy
var newObject = jQuery.extend({}, oldObject);
// Deep copy
var newObject = jQuery.extend(true, {}, oldObject);
References :
14. Difference between shallow copy and deep copy in javascript?
Shallow copy
Shallow copy is a bit-wise copy of an object. A new object is created that has an exact copy of the values in the original object. If any of the fields of the object are references to other objects, just the reference addresses are copied i.e., only the memory address is copied.
let a = { aa : 1 };
let b = a;
b.aa = 2;
console.log(a.aa); // 2
Deep copy
A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. A deep copy occurs when an object is copied along with the objects to which it refers.
let a = { aa : 1 };
let b = JSON.parse(JSON.stringify(a));
b.aa = 2;
console.log(a.aa); // 1
References :
15. How to prevent click action on parent element when user clicks on child element, while both parent and child having click functions?
Here, Event bubbling and Event capturing plays a role.
Using return false;
or e.stopPropogation();
will not allow further code to execute. It will stop flow at this point itself.
$("#clickable a").click(function(e) {
e.stopPropagation();
});
stopPropagation method prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
References :
16. What is the difference between Http post and get?
Here is the key point of GET request
- GET requests can be cached
- GET requests remain in the browser history
- GET requests can be bookmarked
- GET requests should never be used when dealing with sensitive data
- GET requests have length restrictions
- GET requests should be used only to retrieve data
Here is the key point of POST request
- POST requests are never cached
- POST requests do not remain in the browser history
- POST requests cannot be bookmarked
- POST requests have no restrictions on data length
References :
17. How do you find event type when some event happens?
The Event.type
read-only property returns a string containing the event’s type. It is set when the event is constructed and is the name commonly used to refer to the specific event, such as click, load, or error
function getEvtType(evt) {
currEvent = evt.type;
console.log(currEvent);
}
References :
18. Explain about event bubbling and event capturing?
Event bubbling and capturing are two ways of event propagation in the HTML DOM API, when an event occurs in an element inside another element, and both elements have registered a handle for that event. The event propagation mode determines in which order the elements receive the event.
Event capturing
When you use event capturing
| |
---------------| |-----------------
| element1 | | |
| -----------| |----------- |
| |element2 \ / | |
| ------------------------- |
| Event CAPTURING |
-----------------------------------
the event handler of element1 fires first, the event handler of element2 fires last.
Capturing is also called “trickling”, which helps remember the propagation order:
trickle down, bubble up
Event bubbling
When you use event bubbling
/ \
---------------| |-----------------
| element1 | | |
| -----------| |----------- |
| |element2 | | | |
| ------------------------- |
| Event BUBBLING |
-----------------------------------
the event handler of element2 fires first, the event handler of element1 fires last.
We can use the addEventListener(type, listener, useCapture)
to register event handlers for in either bubbling (default) or capturing mode. To use the capturing model pass the third argument as true
element1.addEventListener('click',doSomething2,true)
element2.addEventListener('click',doSomething,false)
To see the detailed explanation about how it works, Check HERE
References :
19. Explain about event delegation?
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
When an event is triggered on an element, the following occurs:
The event is dispatched to its target EventTarget and any event listeners found there are triggered. Bubbling events will then trigger any additional event listeners found by following the EventTarget’s parent chain upward, checking for any event listeners registered on each successive EventTarget. This upward propagation will continue up to and including the Document.
Event bubbling provides the foundation for event delegation in browsers. Now you can bind an event handler to a single parent element, and that handler will get executed whenever the event occurs on any of its child nodes (and any of their children in turn). This is event delegation. Here’s an example of it in practice
<ul onclick="alert(event.type + '!')">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
So what’s the benefit?
Imagine you now have a need to dynamically add new <li>
items to the above list via DOM manipulation:
var newLi = document.createElement('li');
newLi.innerHTML = 'Four';
myUL.appendChild(newLi);
Without using event delegation you would have to “rebind” the “onclick” event handler to the new <li>
element, in order for it to act the same way as its siblings. With event delegation you don’t need to do anything. Just add the new <li>
to the list and you’re done.
Another benefit to event delegation is that the total memory footprint used by event listeners goes down (since the number of event bindings go down). It may not make much of a difference to small pages that unload often (i.e. user’s navigate to different pages often).
References :
20. Explain about how this works in JS?
A function’s this
keyword behaves a little differently in JavaScript compared to other languages. It also has some differences between strict mode and non-strict mode.
Please refer the links for deep understanding about this
in JS.
References :
21. Explain differences between Promises, async and await?
Advanced Questions
1. What is the difference between null and undefined and undeclared ?
undefined is a variable that has been declared but no value exists and is a type of itself ‘undefined’.
null is a value of a variable and is a type of object. It can be assigned to a variable as a representation of no value
undeclared variables is a variable that has been declared without block level scope keyword(such as ‘var’, ‘let’, ‘const’). When former code is executed, undeclared variables are created as global variable and they are configurable (ex. can be deleted).
typeof(a) === undefined; // true
a === undefined; // ReferenceError: a is not defined
var b;
typeof(b) === undefined; // true
b === undefined; // true
var c = null;
typeof(c) // object
null == undefined // true
null === undefined // false
References :
2. What are the ES6 new features?
Listing top features here ==>
- Default Parameters
- Template Literals
- Multi-line Strings
- Destructuring Assignment
- Enhanced Object Literals
- Arrow Functions
- Promises
- Block-Scoped Constructs Let and Const
- Classes
- Modules
Check links for detailed explanations about all other features also.
References :
3. What’s the difference between an attribute and a property?
In the specific context of HTML / Javascript
the terms get confused because the HTML representation of a DOM element has attributes
(that being the term used in XML for the key/value
pairs contained within a tag) but when represented as a JavaScript
object those attributes
appear as object properties
.
To further confuse things, changes to the properties will typically update the attributes.
For example, changing the element.href
property
will update the href
attribute
on the element, and that’ll be reflected in a call to element.getAttribute('href')
.
However if you subsequently read that property, it will have been normalised to an absolute URL, even though the attribute might be a relative URL!
References :
4. What is ‘use strict’ ? Why do we need to use it?
“use strict”; Defines that JavaScript code should be executed in “strict mode”.
Strict mode applies to entire scripts or to individual functions. It doesn’t apply to block statements enclosed in {} braces; attempting to apply it to such contexts does nothing.
Declared at the beginning of a script, it has global scope (all code in the script will execute in strict mode):
"use strict";
myFunction();
function myFunction() {
y = 3.14; // This will also cause an error because y is not declared
}
Features :
- Eliminates some JavaScript silent errors by changing them to throw errors.
- Fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that’s not strict mode.
- Prohibits some syntax likely to be defined in future versions of ECMAScript.
References :
5. Explaing about linting?
Linting is the process of checking the source code for Programmatic as well as Stylistic errors. This is most helpful in identifying some common and uncommon mistakes that are made during coding.
In other words, it’s something that can AUTOMATICALLY find the dumb mistakes we all make, so you can fix them without thinking. It’ll make your code break less and prevent some very confusing problems.
Pros :
- It prevents certain types of bugs, including a few catastrophic ones.
- It saves you time.
- It makes your code better.
- It’s easy.
- It’ll get you laid more.
Lot of tools available for linting in JS such as JSLint, JSHint, JSCS, ESLint
.
References :
6. What is the difference between === and ==? Which situation will prefer one among other?
- == attempts to convert the values to the same type before testing if they’re the same. “5” == 5
- === does not do this; it requires objects to be of the same type to be equal. “5” !== 5
In this case, the result is:
- x == undefined will be true if x is undefined or null.
- x === undefined will only be true if x is undefined.
You should prefer the first method if you’d like undefined
and null
to be treated equivalently.
References :
7. What is the difference between Observer pattern and Pub-Sub pattern?
- The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
- In ‘Publisher-Subscriber’ pattern, senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers.
References :
8. Explain some of the design patterns that you used?
There are lot of design patterns available in software designing. Refere the link below for detailed information. I have listed here some of the frequently used design pattern in frontend techs.
- Singleton Pattern
- Factory method pattern
- Publish–subscribe pattern
- Adapter Design Pattern
- Observer Design Pattern
References :
9. What is SessionState and ViewState? Difference between SessionState and ViewState?
Session State contains information that is pertaining to a specific session (by a particular client/browser/machine) with the server. It’s a way to track what the user is doing on the site.. across multiple pages…amid the statelessness of the Web. e.g. the contents of a particular user’s shopping cart is session data. Cookies can be used for session state.
View State on the other hand is information specific to particular web page. It is stored in a hidden field so that it isn’t visible to the user. It is used to maintain the user’s illusion that the page remembers what he did on it the last time – dont give him a clean page every time he posts back
ViewState | SessionState |
---|---|
Maintained at page level only. | Maintained at session level. |
View state can only be visible from a single page and not multiple pages. | Session state value availability is across all pages available in a user session. |
It will retain values in the event of a postback operation occurring. | In session state, user data remains in the server. Data is available to user until the browser is closed or there is session expiration. |
Information is stored on the client’s end only. | Information is stored on the server. |
used to allow the persistence of page-instance-specific data. | used for the persistence of user-specific data on the server’s end. |
ViewState values are lost/cleared when new page is loaded. | SessionState can be cleared by programmer or user or in case of timeouts. |
10. What is the difference between .map, .every, and .forEach?
The difference is in the return values.
.map()
returns a new Array of objects created by taking some action on the original item.
.every()
returns a boolean – true if every element in this array satisfies the provided testing function. An important difference with .every()
is that the test function may not always be called for every element in the array. Once the testing function returns false for any element, no more array elements are iterated. Therefore, the testing function should usually have no side effects.
.forEach()
returns nothing – It iterates the Array performing a given action for each item in the Array.
Read about these and the many other Array iteration methods at MDN.
11. Can you name two programming paradigms important for JavaScript app developers?
JavaScript is a multi-paradigm language, supporting imperative/procedural programming along with OOP (Object-Oriented Programming) and functional programming. JavaScript supports OOP with prototypal inheritance.
Good to hear:
- Prototypal inheritance (also: prototypes, OLOO).
- Functional programming (also: closures, first class functions, lambdas).
Red flags:
- No clue what a paradigm is, no mention of prototypal oo or functional programming.
Learn More:
- The Two Pillars of JavaScript Part 1 — Prototypal OO.
- The Two Pillars of JavaScript Part 2 — Functional Programming.
Credits : 10 Interview Questions Every JavaScript Developer Should Know
12. What is functional programming?
Functional programming produces programs by composing mathematical functions and avoids shared state & mutable data. Lisp (specified in 1958) was among the first languages to support functional programming, and was heavily inspired by lambda calculus. Lisp and many Lisp family languages are still in common use today.
Functional programming is an essential concept in JavaScript (one of the two pillars of JavaScript). Several common functional utilities were added to JavaScript in ES5.
Good to hear:
- Pure functions / function purity.
- Avoid side-effects.
- Simple function composition.
- Examples of functional languages: Lisp, ML, Haskell, Erlang, Clojure, Elm, F Sharp, OCaml, etc…
- Mention of features that support FP: first-class functions, higher order functions, functions as arguments/values.
Red flags:
- No mention of pure functions / avoiding side-effects.
- Unable to provide examples of functional programming languages.
- Unable to identify the features of JavaScript that enable FP.
Learn More:
- The Two Pillars of JavaScript Part 2.
- The Dao of Immutability.
- Composing Software.
- The Haskell School of Music.
Credits : 10 Interview Questions Every JavaScript Developer Should Know
13. What is the difference between classical inheritance and prototypal inheritance?
Class Inheritance: instances inherit from classes (like a blueprint — a description of the class), and create sub-class relationships: hierarchical class taxonomies. Instances are typically instantiated via constructor functions with the `new` keyword. Class inheritance may or may not use the `class` keyword from ES6.
Prototypal Inheritance: instances inherit directly from other objects. Instances are typically instantiated via factory functions or `Object.create()`. Instances may be composed from many different objects, allowing for easy selective inheritance.
In JavaScript, prototypal inheritance is simpler & more flexible than class inheritance.
Good to hear:
- Classes: create tight coupling or hierarchies/taxonomies.
- Prototypes: mentions of concatenative inheritance, prototype delegation, functional inheritance, object composition.
Red Flags:
- No preference for prototypal inheritance & composition over class inheritance.
Learn More:
- The Two Pillars of JavaScript Part 1 — Prototypal OO.
- Common Misconceptions About Inheritance in JavaScript.
Credits : 10 Interview Questions Every JavaScript Developer Should Know
14. What are the pros and cons of functional programming vs object-oriented programming?
OOP Pros: It’s easy to understand the basic concept of objects and easy to interpret the meaning of method calls. OOP tends to use an imperative style rather than a declarative style, which reads like a straight-forward set of instructions for the computer to follow.
OOP Cons: OOP Typically depends on shared state. Objects and behaviors are typically tacked together on the same entity, which may be accessed at random by any number of functions with non-deterministic order, which may lead to undesirable behavior such as race conditions.
FP Pros: Using the functional paradigm, programmers avoid any shared state or side-effects, which eliminates bugs caused by multiple functions competing for the same resources. With features such as the availability of point-free style (aka tacit programming), functions tend to be radically simplified and easily recomposed for more generally reusable code compared to OOP.
FP also tends to favor declarative and denotational styles, which do not spell out step-by-step instructions for operations, but instead concentrate on what to do, letting the underlying functions take care of the how. This leaves tremendous latitude for refactoring and performance optimization, even allowing you to replace entire algorithms with more efficient ones with very little code change. (e.g., memoize, or use lazy evaluation in place of eager evaluation.)
Computation that makes use of pure functions is also easy to scale across multiple processors, or across distributed computing clusters without fear of threading resource conflicts, race conditions, etc…
FP Cons: Over exploitation of FP features such as point-free style and large compositions can potentially reduce readability because the resulting code is often more abstractly specified, more terse, and less concrete.
More people are familiar with OO and imperative programming than functional programming, so even common idioms in functional programming can be confusing to new team members.
FP has a much steeper learning curve than OOP because the broad popularity of OOP has allowed the language and learning materials of OOP to become more conversational, whereas the language of FP tends to be much more academic and formal. FP concepts are frequently written about using idioms and notations from lambda calculus, algebras, and category theory, all of which requires a prior knowledge foundation in those domains to be understood.
Good to hear:
- Mentions of trouble with shared state, different things competing for the same resources, etc…
- Awareness of FP’s capability to radically simplify many applications.
- Awareness of the differences in learning curves.
- Articulation of side-effects and how they impact program maintainability.
- Awareness that a highly functional codebase can have a steep learning curve.
- Awareness that a highly OOP codebase can be extremely resistant to change and very brittle compared to an equivalent FP codebase.
- Awareness that immutability gives rise to an extremely accessible and malleable program state history, allowing for the easy addition of features like infinite undo/redo, rewind/replay, time-travel debugging, and so on. Immutability can be achieved in either paradigm, but a proliferation of shared stateful objects complicates the implementation in OOP.
Red flags:
- Unable to list disadvantages of one style or another — Anybody experienced with either style should have bumped up against some of the limitations.
Learn More:
- The Two Pillars of JavaScript Part 1 — Prototypal OO.
- The Two Pillars of JavaScript Part 2 — Functional Programming.
Credits : 10 Interview Questions Every JavaScript Developer Should Know
15. When is classical inheritance an appropriate choice?
The answer is never, or almost never. Certainly never more than one level. Multi-level class hierarchies are an anti-pattern. I’ve been issuing this challenge for years, and the only answers I’ve ever heard fall into one of several common misconceptions. More frequently, the challenge is met with silence.
“If a feature is sometimes useful
and sometimes dangerous
and if there is a better option
then always use the better option.”
~ Douglas Crockford
Good to hear:
- Rarely, almost never, or never.
- A single level is sometimes OK, from a framework base-class such as
React.Component
. - “Favor object composition over class inheritance.”
Learn More:
- The Two Pillars of JavaScript Part 1 — Prototypal OO.
- JS Objects — Inherited a Mess.
Credits : 10 Interview Questions Every JavaScript Developer Should Know
16. When is prototypal inheritance an appropriate choice?
There is more than one type of prototypal inheritance:
- Delegation (i.e., the prototype chain).
- Concatenative (i.e. mixins, `Object.assign()`).
- Functional (Not to be confused with functional programming. A function used to create a closure for private state/encapsulation).
Each type of prototypal inheritance has its own set of use-cases, but all of them are equally useful in their ability to enable composition, which creates has-a or uses-a or can-do relationships as opposed to the is-a relationship created with class inheritance.
Good to hear:
- In situations where modules or functional programming don’t provide an obvious solution.
- When you need to compose objects from multiple sources.
- Any time you need inheritance.
Red flags:
- No knowledge of when to use prototypes.
- No awareness of mixins or `Object.assign()`.
Learn More:
Credits : 10 Interview Questions Every JavaScript Developer Should Know
17. What does “favor object composition over class inheritance” mean?
This is a quote from “Design Patterns: Elements of Reusable Object-Oriented Software”. It means that code reuse should be achieved by assembling smaller units of functionality into new objects instead of inheriting from classes and creating object taxonomies.
In other words, use can-do, has-a, or uses-a relationships instead of is-a relationships.
Good to hear:
- Avoid class hierarchies.
- Avoid brittle base class problem.
- Avoid tight coupling.
- Avoid rigid taxonomy (forced is-a relationships that are eventually wrong for new use cases).
- Avoid the gorilla banana problem (“what you wanted was a banana, what you got was a gorilla holding the banana, and the entire jungle”).
- Make code more flexible.
Red Flags:
- Fail to mention any of the problems above.
- Fail to articulate the difference between composition and class inheritance, or the advantages of composition.
Credits : 10 Interview Questions Every JavaScript Developer Should Know
18. What are two-way data binding and one-way data flow, and how are they different?
Two way data binding means that UI fields are bound to model data dynamically such that when a UI field changes, the model data changes with it and vice-versa.
One way data flow means that the model is the single source of truth. Changes in the UI trigger messages that signal user intent to the model (or “store” in React). Only the model has the access to change the app’s state. The effect is that data always flows in a single direction, which makes it easier to understand.
One way data flows are deterministic, whereas two-way binding can cause side-effects which are harder to follow and understand.
Good to hear:
- React is the new canonical example of one-way data flow, so mentions of React are a good signal. Cycle.js is another popular implementation of uni-directional data flow.
- Angular is a popular framework which uses two-way binding.
Red flags:
- No understanding of what either one means. Unable to articulate the difference.
Credits : 10 Interview Questions Every JavaScript Developer Should Know
19. What are the pros and cons of monolithic vs microservice architectures?
A monolithic architecture means that your app is written as one cohesive unit of code whose components are designed to work together, sharing the same memory space and resources.
A microservice architecture means that your app is made up of lots of smaller, independent applications capable of running in their own memory space and scaling independently from each other across potentially many separate machines.
Monolithic Pros: The major advantage of the monolithic architecture is that most apps typically have a large number of cross-cutting concerns, such as logging, rate limiting, and security features such audit trails and DOS protection.
When everything is running through the same app, it’s easy to hook up components to those cross-cutting concerns.
There can also be performance advantages, since shared-memory access is faster than inter-process communication (IPC).
Monolithic cons: Monolithic app services tend to get tightly coupled and entangled as the application evolves, making it difficult to isolate services for purposes such as independent scaling or code maintainability.
Monolithic architectures are also much harder to understand, because there may be dependencies, side-effects, and magic which are not obvious when you’re looking at a particular service or controller.
Microservice pros: Microservice architectures are typically better organized, since each microservice has a very specific job, and is not concerned with the jobs of other components. Decoupled services are also easier to recompose and reconfigure to serve the purposes of different apps (for example, serving both the web clients and public API).
They can also have performance advantages depending on how they’re organized because it’s possible to isolate hot services and scale them independent of the rest of the app.
Microservice cons: As you’re building a new microservice architecture, you’re likely to discover lots of cross-cutting concerns that you did not anticipate at design time. A monolithic app could establish shared magic helpers or middleware to handle such cross-cutting concerns without much effort.
In a microservice architecture, you’ll either need to incur the overhead of separate modules for each cross-cutting concern, or encapsulate cross-cutting concerns in another service layer that all traffic gets routed through.
Eventually, even monolthic architectures tend to route traffic through an outer service layer for cross-cutting concerns, but with a monolithic architecture, it’s possible to delay the cost of that work until the project is much more mature.
Microservices are frequently deployed on their own virtual machines or containers, causing a proliferation of VM wrangling work. These tasks are frequently automated with container fleet management tools.
Good to hear:
- Positive attitudes toward microservices, despite the higher initial cost vs monolthic apps. Aware that microservices tend to perform and scale better in the long run.
- Practical about microservices vs monolithic apps. Structure the app so that services are independent from each other at the code level, but easy to bundle together as a monolithic app in the beginning. Microservice overhead costs can be delayed until it becomes more practical to pay the price.
Red flags:
- Unaware of the differences between monolithic and microservice architectures.
- Unaware or impractical about the additional overhead of microservices.
- Unaware of the additional performance overhead caused by IPC and network communication for microservices.
- Too negative about the drawbacks of microservices. Unable to articulate ways in which to decouple monolithic apps such that they’re easy to split into microservices when the time comes.
- Underestimates the advantage of independently scalable microservices.
Credits : 10 Interview Questions Every JavaScript Developer Should Know
20. What is asynchronous programming, and why is it important in JavaScript?
Synchronous programming means that, barring conditionals and function calls, code is executed sequentially from top-to-bottom, blocking on long-running tasks such as network requests and disk I/O.
Asynchronous programming means that the engine runs in an event loop. When a blocking operation is needed, the request is started, and the code keeps running without blocking for the result. When the response is ready, an interrupt is fired, which causes an event handler to be run, where the control flow continues. In this way, a single program thread can handle many concurrent operations.
User interfaces are asynchronous by nature, and spend most of their time waiting for user input to interrupt the event loop and trigger event handlers.
Node is asynchronous by default, meaning that the server works in much the same way, waiting in a loop for a network request, and accepting more incoming requests while the first one is being handled.
This is important in JavaScript, because it is a very natural fit for user interface code, and very beneficial to performance on the server.
Good to hear:
- An understanding of what blocking means, and the performance implications.
- An understanding of event handling, and why its important for UI code.
Red flags:
- Unfamiliar with the terms asynchronous or synchronous.
- Unable to articulate performance implications or the relationship between asynchronous code and UI code.
Credits : 10 Interview Questions Every JavaScript Developer Should Know