50 JavaScript Interview Questions

50 JavaScript Interview Questions

And their answers explained
Ferenc Almasi • 🔄 2021 November 11 • 📖 21 min read

Preparing for a technical interview is always challenging. What to bring up, what to leave out? What do interviewers want to hear for certain questions? Should I mention other related topics or just stick to the one in question?

These are some of the questions that can come up when you’re right before an interview. To answer all of them, I’ve collected 50 JavaScript questions that often come up during a technical interview so you have one single resource to work from.

If you’re not preparing for an interview just want to learn about JavaScript in general, I invite you to come along and read through as you may not know the answers to all. We can always learn something new so maybe this collection will make you rethink whether you truly know JavaScript or not.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#1 — What is event delegation?

DOM event delegation is used for responding to user events via a single parent rather than each child node. With it, you can bind an event handler to a common parent element that will handle any event happening on one of its children.

This is also useful when we add additional nodes through JavaScript as this way we don’t need to rebind events.

<!-- Instead of doing: -->
<ul>
  <li onclick="console.log(event.type);">One</li>
  <li onclick="console.log(event.type);">Two</li>
  <li onclick="console.log(event.type);">Three</li>
</ul>

<!-- We can do: -->
<ul onclick="console.log(event.type);">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>
delegation.html
Copied to clipboard!

#2 — What are the differences in capturing and bubbling phases?

Event bubbling and capturing are two ways events can be handled in the HTML DOM API. When an event occurs in an element and its parent also registers a handle for the same event, the event propagation model will determine which element should receive the event first.

By default, addEventListener uses bubbling — here the event is first captured in the innermost element and propagates to outer elements.

While in the capturing phase, the opposite happens: the event is captured in the outermost element first and propagates to inner elements.

You can check out the differences at the following pen, change the flag to use bubbling instead of capturing.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#3 — What data types there are in JavaScript?

The ECMAScript standard defines eight different data types, from which seven are primitives. They are:

And we have Object.


#4 — What is the difference between a function expression and function declaration?

For function expressions, you are assigning the function to a variable. In a function declaration, you don’t.

The biggest difference however is that expressions are not hoisted. If you call the function before it was initialized, you will get a type error:

Type error being thrown for function expression
// Function expression
// Will throw a TypeError
console.log(func());
var func = function() { return 5; }

// Function declaration
// Will run without a problem, because it is hoisted
console.log(func());
function func() { return 5; }
functionDeclarations.js
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#5 — What is a callback?

Callbacks are functions passed as an argument to other functions to be used once an event has occurred or a task is finished. Think of an on click event listener attached to a DOM element or a callback provided for a network request:

// This function will only run when the event occurs
const onClick = () => console.log('☝️');

document.addEventListener('click', onClick);
callback.js
Copied to clipboard!

#6 — What are closures in JavaScript?

A closure is an inner function that has access to the outer function’s variables. It’s a combination of a function and the lexical environment in which it was declared. A great example of closures are callbacks. Note the differences between scopes and closures in the following example:

// Note the differences between scope and closure

// scope: global
var a = 1;

(function one() {
  // scope: one
  // closure: one, global
  
  var b = 2;

  (function two() {
    // scope: two
    // closure: two, one, global
    
    var c = 3;

    (function three() {
      // scope: three
      // closure: three, two, one, global
      
      var d = 4;
      
      // This will output 10 as we have access to outer enclosing function variables
      console.log(a + b + c + d);
    })();
  })();
})();
closures.js
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#7 — What is hoisting?

Hoisting means JavaScript will move declarations to the top of every scope. It is often an unknown aspect of JavaScript so to avoid introducing bugs, it’s always a good idea to declare all variables at the top of every scope. It simply means you can use a variable before it has been declared.

It’s important to mention that only variables declared with var are hoisted, let and const declarations are immune.

Initializations are also not hoisted, only declaration.

// Initializations are not hoisted, therefore
// This will log out undefined
console.log(x);

var x = 5;

// Declarations are hoisted, therefore
// This will log out 5
console.log(y);

var y;

y = 5;
hoist.js
Copied to clipboard!

#8 — Is JavaScript a typed language?

JavaScript is weakly typed in its nature. This enables us to use implicit type conversion. Take the following for example:

// This will return "12" as 1 will be converted into a string
1 + "2"
typeof (1 + "2") // Will return "string"

// This will return 12 as "12" will be converted into a number
"12" * 1
typeof ("12" * 1) // Will return "number"
typeConversion.js
Copied to clipboard!

Even though we did not specify we wanted to convert the string/number into the other format, JavaScript did it for us implicitly.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#9 — What is the prototype chain in JavaScript?

Inheritance in JavaScript is called prototypal inheritance. When you try to access a property of an object, the property will not only be looked for in the object but on the prototype of the object, on the prototype of the prototype and this goes on until a matching property is found or we reach the end of the prototype chain.

The same thing goes for methods. In JavaScript, everything is inherited from Object.


#10 — What is the DOM?

The Document Object Model is an API that links HTML and XML document elements — called nodes — into a tree structure. It also holds information about the child-parent relationships between the nodes in the document.

These nodes are objects that can be manipulated through JavaScript and any visible changes made to them — like styles, content, or placement changes — are reflected.

If you would like to learn more about how the DOM is constructed, you can refer to my article about the critical rendering path.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#11 — How can we check if something is an array?

There are various ways to check if something is truly an array:

// Check the constructor
variable.constructor === Array

// Check if the variable is an instance of Array
variable instanceof Array

// Check its prototype
Object.prototype.toString.call(variable) === '[object Array]';

// Use the built in isArray
Array.isArray(obj);
isArray.js
Copied to clipboard!

#12 — How can we merge two arrays?

You can use either Array.concat() or ES6 restructuring:

// Using Array.concat
const array1 = ['📗', '📘'];
const array2 = ['📕', '📙'];

array1.concat(array2);

// Using ES6 destructuring
const array1 = ['📗', '📘'];
const array2 = ['📕', '📙'];

[...array1, ...array2];
merging.js
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#13 — How do you empty an array?

There are a number of ways to do this, probably the simplest is to reassign the variable to an empty array:

let array = [1, 2, 3];

// Assigning to an empty array
array = [];

// Setting its length property to 0
array.length = 0;

// Using splice with the array's length
array.splice(0, array.length);
emptyArray.js
Copied to clipboard!

#14 — What are the different ways we can create objects in JavaScript?

// Using object literals
const obj = { ... };

// Using the new keyword
function Obj(props) {
  this.props = props;
};

const obj = new Obj('👋');

// Using Object.create()
function newObject(props) {
  this.props = props;
};

const obj = Object.create(newObject);

// Using Object.assign()
const obj = { ... };
const copy = Object.assign({}, obj);
objects.js
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#15 — How do you clone objects in JavaScript?

Cloning objects can be tricky because we can either do shallow clone (just copy the object but keep the reference) or deep clone. (creating a new copy with a new reference)

const obj = { ... };

// Shallow copy can be done by using assignment:
const shallow = obj;

// Deep copy examples:
// Using JSON.parse & JSON.stringify
JSON.parse(JSON.stringify(obj));

// Using Object.assign
const deep = Object.assign({}, obj);

// Using object spread
const deep = { ...obj };
copy.js
Copied to clipboard!

#16 — What are the differences between bind, call and apply?

.bind() is used to call a function with a given context. Using .bind() won’t call the function, only modifies the context.

.call() and .apply() will call the function immediately and modifies the context. The difference between the two:

  • .call() accepts a list of values as its arguments
  • .apply() accepts an array as its arguments

Use .bind() when you want to modify the context but you want to call the function later.

Use .call() or .apply() when you want to modify the context and you want to call the function immediately.

If you would like to learn more about function methods, you can refer to my tutorial.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#17 — What is AJAX? What are the cons and pros of it?

AJAX stands for Asynchronous JavaScript And XML and it works in the following way:

Whenever an event occurs on a web page, eg.: a user clicks a button, an XHR request is created by JavaScript that is sent to the server. The server processes the request and returns a response to the web page which is then processed by JavaScript and the necessary actions are taken, eg.: updating the page content.

The pros include:

  • Updating a web page without actually reloading it
  • Request and receive data from the server after the page has been loaded
  • Send data to the server in the background

Some of its cons are:

  • It won’t work in case JavaScript is disabled
  • If history is not taken care of, it can make the browser’s back button useless
  • Since it increases code size, it can make your site vulnerable to security threats

#18 — In which states can a Promise be?

Promise is always in one of the following three states:

  • pending: this is the initial state which we start from
  • fulfilled: this means the promise has been fulfilled successfully.
  • rejected: this means the promise has been rejected, there was an error.

A pending promise can either be fulfilled with a value, or rejected with a reason.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#19 — What are the advantages and disadvantages of using Promises?

Advantages include things like:

  • They are composable, unlike callbacks, therefore we can avoid callback hells
  • You can easily execute code with Promise.all when multiple responses are returned
  • You can wait for only one result from concurrent pending promises with the help of Promise.race
  • You can write asynchronous code in a synchronous manner if you use it in conjunction with async / await.

Some of its disadvantages are:

  • They can only operate on a single value at a time
  • They are not available in older browser, they have to be polyfilled
  • They are slower than using callbacks which can result in possible performance issues.

#20 — What are the differences between a normal script tag vs using async or defer attribute on it?

async is used to continue HTML parsing while the script fetches. On the other hand, defer is used to only execute the script after the HTML parsing is finished. They are both used for optimization purposes. If you would like to read more on HTML optimization, you can do so here.

Differences between defer and async attributes on the script tag
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#21 — What is the difference between local storage and session storage?

Local storage is used for storing data locally on a user’s browser, like saving user preferences or other settings. It is persisted through page reloads and stays with the browser until it is cleared manually or through a setting.

Session storage acts in a similar way to local storage. The only difference here is that while data stored in local storage has an expiration date, the data stored in session storage will expire as soon as the page’s session ends, that’s it, when the page is closed.


#22 — What is the difference between a web worker and a service worker?

Web workers are used for running heavy scripts in a background thread without causing the site to freeze, while Service workers are a type of web workers. They are useful for modifying responses from network requests. They basically act as proxies. They are used for building offline applications.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#23 — What is functional programming?

Functional programming is a programming paradigm. It avoids changing state and mutable data. It focuses more on the what rather than the how. As opposed to being imperative, it uses a declarative approach.

One of the main concepts of functional programming is to be pure:

  • All objects are immutable
  • There is a complete separation between the data and the behavior
  • Uses pure functions wherever it can

It makes your code easily testable and it also makes it easier to reason about.


#24 — What is a pure function?

To consider a function as pure, it must meet two criteria:

  • Given the same input, it should always return the same output
  • The function should not cause any side effects outside of its scope
// This function is pure
// Given the input is 2, 2, the output will always be 4
const sum = (a, b) => a + b;

// This function is not pure
// It will give different results even if the inputs are the same
const rand = (a, b) => Math.random() * (a - b);
pureFunctions.js
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#25 — What is immutability?

Another core principle of functional programming: Simply put, an immutable value can’t be changed after its creation:

const array = [1];

// Method mutating the original array
// array will be [1, 2]
array.push(2);

// Immutable method, creating a new array instead of modifying the original one
// Array will still be [1, 2]
array.slice(1);
immutability.js
Copied to clipboard!

#26 — What is currying?

Currying is a technique where you call a sequence of functions with one argument instead of calling one function with multiple arguments. You call a function with the first argument which returns a function, which you call with the second argument and so on:

// Instead of
const add = (a, b, c) => a + b + c;

add(2, 2, 2);

// Currying does
const curry = (a) => {
    return (b) => {
        return (c) => {
            return a + b + c;
        }
    }
};

curry(2)(2)(2);
currying.js
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#27 — What are first-class functions?

First-class function are functions that you can:

  • Pass as arguments to other functions
  • Store them in a variable
  • Return as values from other functions

#28 — What is the difference between map() and forEach()?

Both of them iterate through the elements of an array. The difference here is that map creates a new array while forEach doesn’t. If you follow the functional programming paradigm and you want to keep data immutable then you should use map. If you want to mutate the elements of the original array, you should use forEach.

To reiterate:

  • forEach mutates the original items in the array
  • map returns a transformed array while keeping the original intact

Note that forEach itself does not mutate the array. However, the callback that you pass to it may do if you choose to.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#29 — Does JavaScript pass by value or by reference?

JavaScript always passes by value, except when a variable refers to an object. In that case, the value is a reference to the object.


#30 — What is the this keyword and how does it work?

The “this” keyword in JavaScript refers to the object it belongs to. By default in the browser, it refers to the global object which is the window.

Keep in mind that if it is used inside an arrow function, it refers to the enclosing scope as arrow functions don’t bind their own context. Also note that if a function is called with bind or callthis will refer to the context passed in as the first parameter.

If you’re interested in the this keyword furthermore, I wrote an article about it which you can reach here:

What Is “this”, After All? — A Look at JavaScript this Keyword
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#31 — What is the difference between lexical and dynamic scoping?

  • Lexical scoping refers to the available variables in the location of a function’s definition.
  • Dynamic scoping refers to the available variables in the location of a function’s invocation.

#32 — What are the potential problems of JS-based applications?

While it provides us:

  • Rich site interactions
  • Fast website rendering after the initial page load
  • Are great for interactive web applications

They come at a price:

  • If they are not implemented correctly, SEO can get a big hit
  • Initial load might require more time as often we require a heavy external library
  • JS-based applications will not work if JavaScript is disabled in the user’s browser
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#33 — What is the typeof operator used for?

The typeof operator is used for getting the data type of its operand:

// This will return "string"
typeof "1"

// This will return "number"
typeof 1

// This will return "boolean"
typeof true

// This will return "undefined"
typeof undefined

// This will return "symbol"
typeof Symbol()

// This will return "object"
typeof []
typeof.js
Copied to clipboard!

#34—What does the following code will return?

typeof typeof 1
typeof.js
Copied to clipboard!

This will return “string” as typeof 1 will return “number” and typeof "number" is a string.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#35 — How do you check if something is NaN?

We can’t use the typeof operator since the type of NaN is surprisingly number. We also can’t do value === NaN since NaN is not equal to itself. But since it is not equal we can check the value against itself: value !== value. If it’s not a number, it will return true. We can also use the new Number.isNaN() function introduced in ES6.

// This will give us "number" as a type
typeof NaN

// We can't do triple equal either since NaN is not equal to itself
value === NaN // retun false
NaN === NaN   // return false

// If value is not equal to itself, we can be sure it is NaN
value !== value

// We can also use the new isNaN Number function introduced in ES6
Number.isNaN(value);
isNaN.js
Copied to clipboard!

#36 — What are design patterns used for?

Design patterns are tested and well-established solutions to commonly occurring software development problems. They are not tied to JavaScript specifically. They are reusable designs to these commonly occurring problems. Each design pattern has a name and we put them into three main categories:

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#37 — What is the difference between i++ and ++i?

Both of them will increment the value by 1. The question is: What they will be evaluated to?

  • i++, called postfix increment will evaluate to the value before it was incremented
  • ++i, called the prefix increment will evaluate to the value after it was incremented
let i = 0;

i++ // Will evaluate to 0
++i // Will evaluate to 1
incrementOperator.js
Copied to clipboard!

#38 — How you do check if something is a palindrome?

A palindrome is a word that reads the same backward as forward. For example:

isPalindrome('noon');  // true
isPalindrome('moon');  // false
isPalindrome('level'); // true
palindrome.js
Copied to clipboard!

This can be achieved in one single line:

// We check if the passed string is equal to the string reversed with split + reverse + join
const isPalindrome = (str) => str === str.split('').reverse().join('');

isPalindrome('noon');  // returns true
isPalindrome('moon');  // returns false
isPalindrome('level'); // returns true
isPalindrome.js
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#39 — What is the output of the code example below?

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0);
}
setTimeout.js
Copied to clipboard!

If you guessed 1, 2, 3, you’ve guessed wrong. It will output 3, three times in a row. This is because setTimeout is a browser API that is deferred to the end of the call stack. By the time the callback function is returned to the call stack, the value of i will already be 3.


#40 — What are the outputs of the function calls below?

const circle = {
  radius: 10,
  diameter() {
    return this.radius * 2;
  },
  
  perimeter: () => 2 * Math.PI * this.radius
};

circle.diameter();
circle.perimeter();
circle.js
Copied to clipboard!

The correct answer is NaNcircle.diameter executes without the problem but perimeter is defined as an arrow function. Arrow functions don’t bind their own context which means this.radius will be undefined. And 2 * Math.PI * undefined will be equal to NaN.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#41 — What is the triple equal operator used for?

The triple equal operator is used to check for strict equality. This means that in order to define two values as equal, both the type and their value must match.

Double equal on the other hand only compares values, meaning different types can be equal if their value matches.

You should always use === to test for equality, otherwise your code may contain unexpected results.

// Here we only check for value
// This will return true:
'1' == 1

// Here we check for both value and type
// While this will return false:
'1' === 1
tripleEqual.js
Copied to clipboard!

#42 — What is the event loop?

In one single sentence: Moving events from the task queue to the call stack is called the “event loop”.

If you would like to dive deeper into how the event loop works, you can refer to my tutorial on it.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#43 — How is JavaScript single-threaded and asynchronous?

JavaScript is single-threaded, it’s true. But the asynchronous behavior is not part of the JavaScript language itself. Asynchronicity is provided on top of the JavaScript engine through the browser APIs.


#44 — What does the second parameter of parseInt do?

It is often overlooked or an unknown part of parseInt, but we have a second parameter which is responsible for the radix: The numeral system to be used.

It can be an integer between 2 and 36. It is always a good practice to define the radix when using parseInt.

// This will return NaN
parseInt(2, 2);

// This will return 2
parseInt(2, 10);
parseInt.js
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#45 — What is the reason for getting “undefined is not a function”?

The error speaks for itself. You want to execute a function. However, what you are trying to execute is evaluated to as undefined. This will throw the following error as it’s basically the same as saying undefined();

Undefined is not a function error shown in Chrome DevTools
Getting the dreaded “undefined is not a function”

#46 — What are short circuits?

Short-circuiting, also often called a short circuit evaluation uses logical operations to return early. They are often used as short if statements or setting default values:

// Short circuit with logical OR
// If this.fileName is undefined, 😶 will be used as a fallback value

const fileName = this.fileName || '😶';

// Short circuit with logical AND
// If hasFireworks is evaluated to true, makeItFestive will be executed
hasFireworks && makeItFestive();

// This is equivalent to:
if (hasFireworks) {
  makeItFestive();
}
shortCircuit.js
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#47 — What are bitwise operators?

Bitwise operators treat their operands as bits: zeroes and ones:

// Bitwise AND - returns 1 in each bit position for which the corresponding bits of both operands are 1
0 & 1 // Returns 0

// Bitwise OR - returns 1 in each bit position for which the corresponding bits of either one of the operands are 1
0 | 1 // Returns 1

// Bitwise NOT - inverts the bits of its operand
~1 // Returns -2
bitwise.js
Copied to clipboard!

#48 — What are the differences between var let and const?

When no keyword is used, the variable will be assigned to the global object which is the window if we are in a browser.

  • var is the default: it creates a function scoped variable which can be reassigned or redeclared later on.
  • let was introduced in ES6 and it is the preferred way over using var. It creates a block-scoped variable which can be reassigned but can’t be redeclared.
  • const was introduced in ES6 along with let. It also creates a block-scoped variable but this can’t be reassigned nor redeclared. const should be used when you don’t want to reassign a value later on.

It’s also good to mention that all declarations will be hoisted to the top of their scope.

var should be avoided if can, use let or const instead.

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

#49 — What are some ES9 features?

A lot of interesting features to come, such as asynchronous iteration, using rest and spread operators for objects or extensions to regular expression such as look behind and named capture groups.

// Using spread operator on objects
const obj = { 'a': 1 };

// This will equal to { 'b': 2, 'a': 1 };
const spread = { 'b': 2, ..obj  };

// Named capturing groups
/(?<year>\d{4})\/(?<month>\d{2})\/(?<day>\d{2})/g.exec('2020/01/02'); // Outputs: ["2020/01/02", "2020", "01", "02", index: 0, input: "2020/01/02", groups: {…}]

/**
 * Groups will include the following:
 * groups:
 *   day: "02"
 *   month: "01"
 *   year: "2020"
 */

// The syntax of positive and negative lookbehinds
/(?<=2020)/ // — Positive lookbehind
/(?<!2020)/ // — Negative lookbehind
es9.js
Copied to clipboard!

#50 — What is the difference between null and undefined?

Both of them represent nothing. The only difference between the two is that null is explicit while undefined is implicit.

When a variable has not been given a value, undefined is inferred. When null is set as the value we explicitly say that there is no value. When we don’t know there’s no value, undefined is used, and when we know there’s no value, null is used.

// This will equal to true
undefined == null

// But this won't
undefined === null

// That's because
typeof undefined  // will be "undefined"
typeof null       // will be "object"

// Hence this will be false as well
typeof undefined == typeof null
nullVsUndefined.js
Copied to clipboard!

These are some common questions that can come around during a JavaScript interview. Going through each of the questions listed here before the great challenge can highly increase your chances of acing it.

It’s important to know that you can always get questions you are not prepared for; The important thing is how you handle these situations. We are all humans, we can’t know all, it’s always fine to say “I don’t know” instead of beating around the bush.

What are your favorite JavaScript questions? Let me know in the comments down below.

Did you find this page helpful?
📚 More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Unlimited access to hundred of tutorials
  • check Access to exclusive interactive lessons
  • check Remove ads to learn without distractions
Become a Pro

Recommended