AI WEEK IS HERE: See All New AI Courses here.
Use Code: LEARNAI to get 21% OFF any membership. Expires soon 👇
00DAYS14HOURS17MINS58SECS

Top 30 JavaScript Interview Questions + Answers (with Code Snippets)

Jacinto Wong
Jacinto Wong
hero image

Are you preparing for a job interview as a front-end developer, and want to brush up on your knowledge?

Well, good news! In this guide, I’m going to share 30 of the most common and relevant interview questions related to JavaScript.

And better still? For each question, I've provided a concise and easy-to-understand answer, along with a code snippet that illustrates the concept in action. This means, no more awkward situations of actually knowing an answer, but not being able to clearly explain it!

Sidenote:

Ideally, you should know the answers to all these questions before sitting your interview, and just use this guide as a reminder / last minute prep.

However, if you find that you’re really struggling to understand some of the concepts, then be sure to check out Andrei’s complete Web Developer bootcamp to get a better understanding of the core elements of JavaScript, as well as his advanced JavaScript concepts course.

advanced javascript concepts

Also, if you want to put these principles into practice and build a stand out portfolio, then check out my top 20 JavaScript projects course.

javascript projects

Those 3 resources will not only cover any issues that you may encounter while learning this language, but they’ll also get you to the level where interviewers are seriously blown away with your skills.

(No joke, you can go from trying to get hired, to recruiters actively trying to bring you in instead!)

10x developer

Anyways, with all that out of the way, let’s get into these interview questions!

Beginner JavaScript interview questions

Some of these questions will seem super basic or obvious, and you might think “Why on earth would an interviewer ever ask these of me?”.

The simple fact is that some initial interviews are done by non-technical people first as a quality filter, and they might ask simple questions around the language.

This means that it's worth being able to answer the basics very confidently and concisely to make sure you get past the gatekeeper and advance through to a 2nd interview with team leads where you'll get more advanced questions and/or live coding tests.

#1. What is JavaScript? What are some of its core ‘stand-out’ features?

JavaScript (also commonly known as JS), is a high-level programming language that is used to create interactive elements on the web.

One of the cool things about JavaScript is that it can change the content of a web page without needing to reload the whole thing.

For example: when you click on a button on a website and something happens, such as a new message appearing, that's often because of JavaScript, and it leads to a much better user experience.

JavaScript also has some other special features that make it powerful:

  • It can ‘handle events’, which means it can respond to things like mouse clicks and keystrokes
  • It can create objects, which are like containers that can hold data and perform actions
  • JavaScript is also flexible in how it handles data. Unlike some other programming languages, you don't need to specify what kind of data a variable will hold. For example, you could create a variable called "x" and set it equal to a number, a string of text, or even an entire object

#2. What is the difference between let and var?

In JavaScript, both let and var are used to declare variables, but they have some key differences in how they are scoped.

For example

Variables declared with var are function-scoped, meaning that they are visible throughout the entire function in which they are declared.

While variables declared with let are block-scoped, meaning that they are visible only within the block in which they are declared. (A block is typically defined by curly braces, such as in a loop or an if statement).

Another practical difference between let and var is that using let can help avoid bugs caused by variable hoisting.

(Variable hoisting is a behavior of JavaScript where variables declared with var are "hoisted" to the top of the function scope, even if they are declared later in the code.)

As you can imagine, this can lead to unexpected results if you are not careful, so here's a walkthrough of what might happen.

function example() {
  var x = 10;
  if (true) {
    let y = 20;
    console.log(x, y); // 10, 20
   }
   console.log(x, y); // throws an error, y is not defined
}
example();

In this code snippet, we’ve defined a function called example that declares two variables, x and y.

x is declared with var, while y is declared with let. We then use console.log to output the values of x and y within the if block, and again after the if block.

As you can see in the image above, because x is declared with var, it is visible throughout the entire function, so we can output its value both inside and outside the if block.

However, because y is declared with let, it is only visible within the if block. This means that if you try to output the y value outside the block it will result in an error, because y is not defined in that scope.

#3. What is the difference between null and undefined?

In JS, null and undefined are both used to represent the absence of a value, but they have different meanings.

null represents a deliberate non-value, often used to indicate that a variable intentionally has no value.

On the other hand, undefined represents a value that has not been initialized, often caused by a variable that has been declared but not assigned a value as in the previous answer.

var x = null;
var y;
console.log(x === null); // true
console.log(y === undefined); // true

In this code snippet, we define two variables, x and y. We set x equal to null, which explicitly indicates that x has no value.

We do not set a value for y, which means that it is automatically initialized to undefined.

We then use console.log to compare x and y to null and undefined, respectively.

In both cases, the comparison evaluates to true, indicating that x and y have the expected values.

#4. What is an example of an asynchronous function?

setTimeout is a great example of an asynchronous function in JavaScript.

It’s used to delay the execution of a piece of code by a specified amount of time, and is often used to simulate a long-running operation, such as a network request.

console.log('Before setTimeout');
setTimeout(function() {
  console.log('Inside setTimeout');

}, 1000);
console.log('After setTimeout');
// Output:
// Before setTimeout
// After setTimeout
// Inside setTineout

The setTimeout function is called with a delay time of 1000 milliseconds (1 second), and a callback function that outputs the message "Inside setTimeout" to the console.

This means that the message will be delayed by 1 second before it is output to the console.

#5. How would you expect == to behave differently from === ?

Although you might not think it, the amount of equal signs is very important.

Using just one = will assign a value, (which admittedly, is something I’ve done unintentionally once or twice), while == and === are both used to compare values, but they have different rules.

== is known as the "loose equality" operator, because it will try to convert the values being compared to a common type before making the comparison.

On the other hand, === is known as the "strict equality" operator, because it does not allow for type coercion, and requires that the types of the values being compared match exactly.

console.log(1 == '1'); // true
console.log(1 === '1'); // false

In this example, we use console.log to compare the values 1 and '1' using both == and ===.

As you can see, when we use ==, the comparison returns true, because JavaScript converts the string '1' to a number before making the comparison.

However, when we use ===, the comparison returns false, because the types of the values do not match exactly.

This demonstrates the importance of understanding the difference between == and === when comparing values in JavaScript.

If you are not careful, using the wrong operator can lead to unpredictable results, especially when dealing with different data types. As a best practice, it is generally recommended to use === for strict equality comparisons whenever possible.

#6. What are the benefits of using a ternary operator?

The ternary operator is a shorthand way of writing an if statement that has a single expression for both the true and false cases.

Also, the ternary operator can make your code more concise and easier to read, especially in cases where you need to make a simple comparison and return a value based on the result.

However, it's important to note that the ternary operator is not always the best choice for every situation, and in some cases, an if statement may be more appropriate.

var age = 18;
var canVote;

// Using a ternary operator
canVote = (age >= 18) ? 'Yes' : 'No';
console.log(canVote); // 'Yes"

// Using an if statement
if (age >= 18) {
  canVote = "Yes';
} else {
  canVote = 'No';
}  
console.log(canVote); // 'Yes"

In the image above, you can see how both the ternary operator and if statements can be used to achieve the same result, and how you can choose the appropriate approach based on the specific requirements of your code.

In general though, the ternary operator is a good choice for simple comparisons that return a single value, while if statements are better suited for more complex logic or multiple expressions.

#7. What is a template literal and how is it used?

A template literal allows for string interpolation, which means that you can embed expressions inside the string literal.

This can be useful for creating more dynamic and flexible strings, such as HTML or SQL queries, where you need to include dynamic values or expressions.

var num = 42;
var message = "The answer to the ultimate question of life, the universe, and everything is ${num].";

console.log (message); // 'The answer to the ultimate question of life, the universe, and everything is 42.'

In this code snippet, we declare a variable num and set its value to 42.

We then use a template literal to create a string that includes the value of the num variable.

(The syntax for a template literal is to enclose the string in backticks instead of single or double quotes, and to use ${} to embed expressions inside the string).

You can use template literals to create more readable and maintainable code, by avoiding the need for concatenation or complex string manipulation.

This is especially useful when you are giving some kind of alert to the user about updating a record, you can always pass the name of whatever they just updated dynamically.

#8. Why is it better to use textContent instead of innerHTML?

Both textContent and innerHTML are used to manipulate the contents of an HTML element. However, there are some important differences between the two that make textContent a better choice.

The main difference between textContent and innerHTML is that textContent sets or retrieves only the text content of an element, while innerHTML sets or retrieves both the HTML content and the text content of an element.

This means that because textContent only deals with the text content of an element, it is generally faster and safer to use than innerHTML.

Not only that, but it's also more secure, thanks to the fact that textContent does not parse HTML tags or execute scripts, which can lead to security vulnerabilities and performance issues when using innerHTML.

In general, it is a good practice to use textContent whenever you need to manipulate the text content of an element, and to use innerHTML only when you need to manipulate the HTML content of an element.

#9. What are some common libraries and frameworks used in JavaScript?

Everyone will have a different answer if asked what their library or framework of choice is. I’m personally most familiar with Angular, after starting out learning React.

Both of these (and many others) are somewhat similar and at their core in that they are all JavaScript. They simply allow you to automate more of the process, using and re-using pre-built components, services, etc.

jQuery is a widely used library that makes it easier to manipulate HTML documents, handle events, and create animations.

Developers can write less code and achieve more functionality in some cases. It is actually easier in the sense that you can target any HTML element by almost any property and interact with it.

React is a library that enables developers to build fast, scalable, and dynamic user interfaces.

It is often used for creating single-page applications, mobile apps, and other interactive web experiences. Originally invented by Facebook as they were scaling their platform.

Angular is a popular framework that is well-documented and has a lot of tooling that automates things like making a progressive web app using the Angular CLI.

Google maintains it, and has a large and active community of developers contributing to its development.

There are many other libraries and frameworks available in JavaScript, each with their own strengths and weaknesses.

At the end of the day, your choice of library or framework depends mainly on your specific project requirements, your familiarity with the tool, and the overall community support and development behind it.

Andrei does a great job breaking down the pros and cons of React vs. Angular vs. Vue in this article here, if you want to dive deeper into three of the most popular JavaScript frameworks.

#10. How do you keep up with the latest developments in JavaScript?

Interviewers are trying to guage your curiosity and interest level. Generally speaking, people who truly "geek out" will end up being more successful than people who just want a job.

And since the industry evolves and changes so fast, you constantly need to be learning new things.

So it's important to show interviews how you're staying up-to-date.

There are a few different options:

  • Reading popular blogs (ex: JavaScript Weekly, Hackernoon, etc.) and newsletters is the easiest way (ex: Andrei's Web Developer Monthly newsletter)
  • Attending conferences and meetups is a great way to meet other developers and learn new things
  • There are many online communities for JavaScript developers, including forums, chat rooms, and social media groups
  • Applying what you learn in new projects! It’s not a new source, but showing that you're actually trying out new things on your own projects (and being able to explain why they are good or not good) is infinitely more valuable than only knowing what they are

Intermediate JavaScript interview questions

#11. What are higher-order functions? Can you give an example?

A higher-order function takes one or more functions as arguments, or returns a function as the result, which allows for more concise and reusable code.

There are many ways to use higher order functions, but they are commonly used in functional programming, as well as in popular libraries and frameworks like React and Redux.

function multiplyBy(factor) {
  return function (number) {
    return number * factor;
  };
}

const double = multiplyBy(2);
const triple = multiplyBy(3);

console.log(double(4)); // Output: 8
console.log(triple(4)); // Output: 12

For example

multiplyBy is a higher-order function that returns a new function that multiplies a given number, while the returned function is a closure that has access to the factor argument even after the multiplyBy function has returned.

We then use the multiplyBy function to create two new functions, double and triple, that multiply a given number by 2 and 3.

We can then call these functions with a number argument to get the result.

#12. What's the difference between a callback function and a Promise?

In JavaScript, a callback function is a function that is passed as an argument to another function and is called when that function has completed its task.

A Promise, on the other hand, is an object that represents the eventual completion or failure of an asynchronous operation, and allows for more flexibility when handling an error by using the built-in .catch() method.

// Example using callback function
function fetchData(callback) {
    const data = ['apple', 'banana', 'cherry'];
    callback(data);
}

fetchData((data) => {
  console.log(data); // Output: ['apple', 'banana', 'cherry']
});

// Example using Promise
function fetchDataPromise() {
  return new Promise((resolve, reject) => {
    const data = ['apple', "banana', 'cherry'];
    resolve(data);
    reject(error);
  });
}

fetchDataPromise()
.then((data) => 4 {
  console.log(data); // Outputs ['apple', 'banana', 'cherry']
})
.catch((error) => {
  console.log(error message); // Output: "Failed to fetch data"
  });

In both examples, we are using the hard-coded data array as the value, but you would usually have a GET call instead that is returning data.

In the first example, it would receive this data and then execute the callback function once complete to console.log the output in this case.

But in the second example, you would have some logic to decide whether or not to resolve or reject the promise. The benefit of the promise is that it has built-in methods to catch the error or execute the console.log when data is returned.

#13. How does the ‘this’ keyword work?

In JavaScript, the this keyword refers to the object that the current function or method is a property of, or the object that the function is invoked on, and can have different values depending on how a function is called.

const person = {
  name: 'John', 
  age: 30,
  sayHello() {
    console.log('Hello, my name is $(this.name));
   },
 };

person.sayHello(); // Output: "Hello, my name is John"

const greet = person.sayHello;
greet(); // Output: "Hello, my name is undefined"

In this example, we are able to pass the name John correctly and the this keyword refers to the person object.

However, when we try to assign the sayHello method to the variable greet, it becomes a stand-alone function and the name becomes undefined. The reason is that this refers to the global variable and not the person object the sayHello function is a method of.

This is something I’d commonly use in Angular to define global variables, created above the constructor, which are very helpful in allowing for different functions to share the same value.

#14. Explain the concept of prototypal inheritance and why you might use it

Prototypal inheritance is a mechanism where an object can inherit properties and methods from another prototype object. This means that every object has a prototype, which is an object that serves as a template for the new object…

Let me clear this up with an example.

// Parent object
const animal = {
  type: 'unknown',
  eat() {
    console.log('The $(this.type} is eating.');
  },
};

// child object
const dog = Object.create(animal);
dog.type = 'dog';
dog.eat(); // Output: 'The dog is eating.'

Here you can see that animal is a prototype object and the dog object is inheriting the type property, as well as the eat method.

And because the dog object is created using Object.create, the type is then passed and when the dog.eat() method is called, it is able to console.log the type correctly, as so:

“The dog is eating”.

The benefits of using prototype objects like this is that it allows you to create hierarchies and reuse code in a more flexible and modular way.

#15. Can you give an example of when you would use map(), filter(), reduce()?

map(), filter(), and reduce() are three commonly used array methods that allow developers to work with arrays in a more concise and functional way.

map() example

map() is used to create a new array by mapping each element of an existing array to a new value using a callback function, which takes three arguments:

  • the current element
  • the index of the current element, and
  • the original array

Here's an example of using map() to create a new array of squared values:

const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = numbers.map(num => num ** 2);
console.log(squaredNumbers); // Output: [1, 4, 9, 16, 25]

filter() example

filter() is used to create a new array containing only the elements of an existing array that pass a certain condition, as determined by a callback function.

Note: The callback function takes the same three arguments as the map() method.

  • the current element
  • the index of the current element, and
  • the original array

Here's an example of using filter() to create a new array of even numbers:

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter (num => num % 2 === 0);
console.log(evenNumbers); // Output: [2, 4]

reduce() example

reduce() is used to reduce an array to a single value by applying a callback function to each element of the array, accumulating the results as it goes.

The callback function takes four arguments:

  • the accumulator (which holds the current accumulated value)
  • the current element
  • the index of the current element, and
  • the original array

Here's an example of using reduce() to find the sum of an array of numbers:

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) => acc + num, O);
console.log(sum); // Output: 15

#16. What are the different ways to create an object? Which one do you prefer?

There are several ways to create objects and the simplest and most used method is object literals. They are created with curly braces ‘{}’ and include key-value pairs separated by ‘:’ as below:

const person = {
  name: 'John', 
  age: 30,
  sayHello() {
    console.log('Hello, my name is $(this.name]');
  },
};

Another option, introduced in ES6 is the ability to use class syntax. This is an option with more flexibility as it allows you to dynamically pass values.

In the example below, we’re passing the name and age separately, meaning this could be re-used in this case for many users.

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

   sayHello() {
    console.log('Hello, my name is $(this.name]');
   }
}
const person = new Person('John', 30);

The choice of which option to use is more personal preference, but I believe that if your goal is reusability then using the class syntax is the way to go.

#17. What is an example of how errors can be handled?

There is more than one way for errors to be handled, so here are a few methods.

Option #1. Catch blocks

Catch blocks are used for errors that occur during the execution of a method.

If there is an error in the try block, it will automatically pass the error to the next part of the function, in this case, console.logging it, but in the real world, you’d probably have a pop-up message for the users.

try {
  // Code that may cause an error
  const result = x / y;
} catch (error) {
  // Code to handle the error
  console.log(error.message);
}

Option #2. Error objects

Another example are error objects, which are used to represent and handle errors.

They have properties, including ‘name’ and ‘message’ and can be customized to give more specific information.

The below example is using the ‘message’ property.

function divide(x, y) {
  if (y === 0) {
    throw new Error('Cannot divide by zero');
  }
  return x / y;
}

try {
  const result = divide(10, 0);
} catch (error) {
  console.log(error message);
}

#18. When would you use a for loop or a forEach loop?

For loops and forEach loops are both used to iterate through arrays and perform some operation on each item within the array.

For loops use a counter variable, in this case represented by the ‘i’ variable.

This does make it easier to always pass this value as an index within the function itself. It also allows you to more easily go backwards through the loop, or it’s helpful if you have to loop through multiple arrays at once. (The console log would happen 5 separate times with a new number each time).

const numbers = [1, 2, 3, 4, 5];

for (let i = 0; i < numbers.length; i++) {
  console.log(numbers[i]; // Console Output: 1 2 3 4 5

In this example, the console output is the same using a forEach loop, but you can see that the code is a little more concise, we don’t have to worry about adding the length of the array and iterating the index.

const numbers = [1, 2, 3, 4, 5];
numbers.forEach ((number) => {
  console.log(number); // Console Output: 1 2 3 4 5
});

Ultimately, for loops are useful when you need to loop over an array and perform complex operations on each element, such as sorting or filtering, while ForEach loops are useful when you need to perform a simple operation on each element, such as logging or modifying the values.

#19. What is the difference between the setTimeout() and setInterval() methods?

The setTimeout() and setInterval() methods are like JavaScript's in-house timekeepers, helping you execute code after a certain amount of time has passed.

Although they share some similarities, there are key differences between these two methods.

setTimeout() swoops in to run a function just once after a specified number of milliseconds. It needs two arguments: the function to run and the milliseconds to wait before doing so.

function greet() {
  console.log("Hello!");
}
setTimeout (greet, 1000);

In our example, setTimeout() is called to run the greet() function after a 1000-millisecond pause (aka one second). The function only gets executed once.

On the other hand, setInterval() is the go-to method for running a function repeatedly at a specified interval. It also takes two arguments: the function to run and the milliseconds to wait between each execution.

let count = 0;

function incrementCount() {
  console.log('Count is now $(count}');
  count++;
}

setInterval(incrementCount, 1000);

In this case, setInterval() is used to run the incrementCount() function every 1000 milliseconds (yes, one second again). The function keeps going, upping the count variable each time.

The key distinction between setTimeout() and setInterval() is that the first runs the specified function just once, while the latter keeps the party going at the specified interval.

In general, reach for setTimeout() when you need a function to run after a delay, and setInterval() when you want a function to run repeatedly at a specific interval.

Just remember to use these methods wisely, as overuse can lead to performance hiccups and other headaches.

#20. What is the event loop? How does it work?

The event loop is an important part of the runtime that handles asynchronous code execution in a single-threaded environment.

It works by always looping over two main components:

  • the call stack, and
  • the task queue

The call stack is a data structure that tracks the execution of function calls. When a function is called, it is added to the top of the call stack, and when it finishes executing, it is removed from the stack.

(The task queue is a data structure that tracks events that have completed, but have not yet been added to the call stack).

These events are typically asynchronous in nature, such as user input or network requests, and so when an asynchronous event occurs, it is added to the task queue.

console.log('Start');

setTimeout(function() {
  console.log('Timeout');
}, 0);

Promise.resolve('Promise'), then(function (value) {
  console.log(value);
});

console.log("End');

// Console Output:
// Start
// End
// Promise
// Timeout

In this example, we have a setTimeout() function that is set to execute after 0 milliseconds, and a Promise that is resolved immediately. We also have some console.log() statements to track the order of execution.

It starts with executing the ‘Start’ and ‘End’ logs, then the call stack is empty, so the task queue is then checked to find the Promise which gets resolved to output ‘Promise’.

With the call stack empty again, it loops through to find the setTimeout which gets executed last.

Advanced JavaScript interview questions

#21. Explain the difference between shallowCopy and deepCopy in JavaScript?

When we copy an object or an array, we can create either a shallowCopy or a deepCopy.

The main difference between them is that the shallowCopy of the object will continue to affect the original object, whereas the deepCopy will remain entirely separate.

//Original object
const original = {
  name: "John", 
  age: 30, 
  hobbies: ["reading", "cooking"],
  address: {
    city: "New York", 
    state: "NY"
};

// Shallow copy
const shallowCopy = Object.assign({}, original);

// Deep copy
const deepCopy = JSON.parse(JSON.stringify(original));

// Modifying a nested object
shallowCopy.address.city = "San Francisco";
deepCopy.address.city = "Los Angeles";

console.log(original.address city); // Output: "San Francisco" 
console.log(shallowCopy.address.city); // Output: "San Francisco" 
console.log(deepCopy.address.city); // Output: "Los Angeles"

We can see this occur when we try to modify the nested city property in the image above.

In the shallowCopy, the original city is changed from New York to San Francisco, whereas the deepCopy city of Los Angeles does not affect the original city.

#22. What design pattern do you prefer to use in JavaScript?

Design patterns are like secret recipes for crafting high-quality, manageable, and scalable code.

Among my favorites is the Module Pattern. It’s a powerful design pattern for creating organized, maintainable, and scalable code. It neatly bundles code into reusable modules for various applications or parts of the same app, while also preventing naming collisions, simplifies code, and enhances reusability.

The magic of the Module Pattern lies in the immediately invoked function expression (IIFE), which protects a module's variables and functions from global scope pollution and collisions.

const calculator = (function() {
  // Private variables and functions
  let result = 0;

function add(a, b) {
  result = a + b;
}

function subtract(a, b) {
result = a - b;
}

// Public API
return {
  getResult: function() {
    return result;
},

    add: add,

    subtract: subtract
  };
})();

calculator.add(5, 3);
console.log(calculator.getResult()); // Output: 8 

calculator.subtract (10, 4);
console.log(calculator.getResult()); /// Output: 6

In our example, we have a calculator module with add and subtract functions, which update a private result variable. The getResult method makes this variable public.

Our IIFE bubble wraps the module's code, keeping add and subtract functions hidden from outsiders.

#23. What are generators in JavaScript? Can you give an example of when you would use one?

Generators let developers wield control over JavaScript's flow of iteration, so that we can pause and play on demand, conjuring up a sequence of values over time.

We can implement this by using an asterisk (*) after the function keyword. We can then hit the pause button with the yield keyword, which returns a value and bookmarks the generator's state.

To hit play again, we just use the next() method, picking up where we left off.

Generators shine in various scenarios where we need to unveil a sequence of values over time, such as handling asynchronous data or processing giant datasets.

By letting us pause and play the value generation, generators are our secret weapon for controlling JavaScript's flow of iteration.

For example, we could create a generator function called fibonacci to whip up a sequence of Fibonacci numbers.

function* fibonacci() {
  let a = 0;
  let b = 1;

  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

const fib = fibonacci();

console.log(fib.next().value); // Output: 0 
console.log(fib.next().value); // Output: 1
console.log(fib.next().value); // Output: 1
console.log(fib.next().value); // Output: 2
console.log(fib.next().value); // Output: 3
console.log(fib.next().value); // Output: 5

With variables a and b set to 0 and 1, our generator dives into an infinite loop, yielding a's current value and updating a and b to the next pair of Fibonacci numbers.

Next, we summon a generator instance using the fibonacci function and store it in a variable named fib. This means that with the next() method, we can stroll through the Fibonacci sequence, starting at 0 and 1.

#24. How would you effectively use every() or some() methods?

The every() and some() methods are like the dynamic duo of JavaScript array methods, helping developers quickly figure out if all or just a few elements in an array meet specific criteria.

They're perfect for writing sleek and efficient code for common array tasks, like searching for a particular value or seeing if all elements pass a certain test.

every() explained

The every() method checks if all elements in an array meet a particular condition.

It uses a callback function that runs for each element, and returns true if the callback is true for all elements, and false otherwise.

const numbers = [1, 2, 3, 4, 5];

const allGreaterThanZero = numbers.every((num) => num > 0);
console.log(allGreaterThanZero); // Output: true

const allGreaterThanThree = numbers.every((num) => num > 3);
console.log(allGreaterThanThree); // Output: false

In our example, we employ the every() method to see if all elements in the numbers array are greater than zero or greater than three.

The callback function says "yay" (true) if the current element is greater than the given value, and "nay" (false) otherwise.

The every() method gives a thumbs up (true) when all elements pass, and a thumbs down (false) otherwise.

some() explained

The some() method is quite similar to every(), but it's satisfied with just one element in the array meeting the condition.

Here's an example:

const numbers = [1, 2, 3, 4, 5];

const someGreaterThanThree = numbers.some((num) => num > 3);
console.log (someGreaterThanThree); // Output: true

const someGreaterThanFive = numbers.some((num) => num > 5);
console.log(someGreaterThanfive); // Output: false

In this case, we use the some() method to check if any elements in the numbers array are greater than three or greater than five. The callback function gives a "yup" (true) if the current element is greater than the given value, and "nope" (false) otherwise.

The some() method is content (true) with at least one element meeting the condition, and unhappy (false) otherwise.

To sum it up, the every() and some() methods are great for verifying if all or some elements in an array meet specific conditions. They provide a snappy and effective way to handle common array operations, boosting code readability and minimizing the risk of bugs.

#25. What is the event-driven programming paradigm? How does it work?

JavaScript uses event-driven programming to craft dynamic, interactive user interfaces, where the program's flow is driven by events happening in the system, rather than a fixed set of instructions.

In this paradigm, the program patiently awaits events like a user clicking a button or typing into a form field. When an event pops up, the program jumps into action, executing a predefined function or a callback function to handle the event.

JavaScript leans on the browser's Document Object Model (DOM) to manage events. The DOM is a family tree-like structure that represents the web page and lets you mingle with the different elements on it.

  • When an event takes place, say, a user clicking a button, the DOM whips up an event object filled with info about the event, like the target element and event type
  • This event object is handed over to a registered callback function
  • The callback function then jazzes up the web page in response to the event, such as changing an element's text or updating a form field's value
// Get the button element
const button = document.getElementById("myButton");

// Register an event listener for the "click" event
button.addEventListener("click", function(event) {
  // Handle the click event 
  console.log("Button clicked!");
});

In our example, we grab a button element using the document.getElementById() method.

Next, we sign up an event listener for the "click" event with the addEventListener() method.

When the button is clicked, the callback function we passed to addEventListener() springs into action, and "Button clicked!" is logged to the console. Huzzah!

All in all, event-driven programming is a powerful way to create lively, interactive web apps in JavaScript. By reacting to events in the system, we can design user interfaces that are responsive, intuitive, and delightful.

#26. What is the difference between a module and a namespace in JavaScript?

Modules and namespaces both offer ways of organizing code and dodging naming collisions, but there are subtle differences.

Modules explained

A module is a self-contained code unit packed with variables, functions, classes, or other code catering to a specific task or feature. Modules are great for breaking a large app into smaller, easier-to-handle pieces and keeping naming collisions at bay.

With ES6, JavaScript rolled out a built-in module system, letting developers effortlessly create, import, and export modules. Just use the export keyword to export a module and the import keyword to bring it in.

// Modulel.js
export const message = "Hello, world!";

// Module2.js
import {message} from './Modulel.js'; 
console.log(message); // "Hello, world!"

Namespaces explained

Namespaces help avoid naming collisions in sprawling applications. They are all about grouping related variables, functions, or objects under one roof.

You can create namespaces using an object literal and even nest them for a hierarchy.

// Create a namespace called "MyApp"
var MyApp = {};

// Add some properties to the namespace
MyApp message = "Hello, world!";
MyApp.sayHello = function() {
  console.log(MyApp.message);
};

// Call the sayHello() function
MyApp.sayHello(); // "Hello, world!"

In our example, we whip up a namespace called "MyApp" using an object literal. Next, we add some properties, like a message property and a sayHello() function.

By bundling these properties within a namespace, we dodge naming collisions with other parts of the app.

So, in a nutshell, modules and namespaces both keep JavaScript code organized and naming collisions at arm's length, but they serve distinct purposes. Modules craft self-contained code units that can be imported and exported in one piece, while namespaces corral related variables, functions, or objects under one name.

#27. What are decorators? How do you use them?

Decorators in JavaScript let you tweak the behavior of a class or function using a simple, elegant syntax. And as an added bonus, decorators play nice with classes, methods, and properties.

To use a decorator, just pop the @ symbol in front of the decorator function's name.

// Define a decorator function
function log(target) {
  console.log(target.name + "was called");

// Apply the decorator to a class
@log
class MyClass {
// Class implementation goes here

In our example, we whip up a decorator function called "log" that logs a message to the console. We then apply the decorator to a class named "MyClass" using the @log syntax.

As MyClass comes to life, the decorator function springs into action, logging "MyClass was called" to the console.

Decorators can also mingle with methods and properties, modifying their behavior. You could conjure a decorator that caches a function's result or one that adds validation to a property.

// Define a decorator that adds validation to a property
function validate(target, name, descriptor) {
  const originalSet = descriptor.set;

  descriptor.set = function(value) {
   if (typeof value !== "string") {
    throw new Error ("Invalid value");
   }
   originalSet.call(this, value);
  }

  return descriptor;
}

// Apply the decorator to a class property
class Person {
  @validate
  set name(value) {
    this._name = value;
}

get name() {
  return this._name;
  }
}

const person = new Person(); 
person.name = "John"; 
console.log(person.name); // "'John'

person name = 123; // Throws an enror "Invalid value"

In another example, we craft a decorator function named "validate" that bestows validation on a property.

The decorator function tweaks the property's descriptor to intercept setter method calls and validate the input. If the input doesn't pass muster, an error is thrown. Next, we apply the decorator to the "name" property of a Person class, ensuring only strings are assigned to the property.

In a nutshell, decorators are a fantastic JavaScript feature that modifies the behavior of classes, methods, and properties in a flexible and reusable manner. With decorators, you can add nifty features like logging, caching, or validation to your code without drowning it in boilerplate.

#28. What is the difference between the async and defer attributes on a &lt;script> tag in HTML?

The async and defer attributes work with HTML's &lt;script> tag to manage script loading and execution.

The async attribute instructs the browser to download the script asynchronously while parsing the rest of the HTML document.

Why do this?

Simply because the script runs as soon as it's downloaded, even if the document hasn't fully loaded. This approach can speed up page load times, especially for non-critical scripts.

<script> async src="myscript.js"></script>

Conversely, the defer attribute tells the browser to download the script asynchronously but hold off on execution until the entire HTML document is parsed.

This means the script runs in the order it appears in the HTML document, after the DOM is fully constructed. This method also boosts page load times, particularly for DOM-manipulating scripts.

<script> defer src="myscript.js"></script>

In essence, the distinction between async and defer lies in script execution timing. Async scripts run as soon as they're downloaded, while defer scripts wait until the DOM is completely constructed.

The choice between the two depends on your script's specific needs and its interaction with the page.

#29. What is the difference between localStorage and sessionStorage?

localStorage and sessionStorage are JavaScript APIs that let web apps store data client-side, right in the browser, but they do have some key differences.

localStorage explained

localStorage is a persistent storage buddy, hanging onto your data even after you close the browser or restart your computer.

It's great for long-term data like user preferences or settings. Plus, it's a social butterfly, sharing data across tabs and windows in the same browser.

sessionStorage explained

sessionStorage, though, is more of a short-term pal. It sticks around only during the current browsing session, and its data disappears once you close the window or tab.

It's perfect for temporary data, like user input or state data for specific workflows.

They do have some similarities of course.

localStorage and sessionStorage both use key-value pairs and offer similar APIs like setItem(), getItem(), and removeItem() for data manipulation.

The main difference is simply how long the data sticks around.

// Store data in localStorage 
localStorage.setItem("user", "John");

// Retrieve data from localStorage
const user = localStorage.getItem("user");

// Remove data from localStorage 
localStorage.removeItem("user");

// Store data in sessionStorage 
sessionStorage.setItem("tempdata", "Some temporary data");

// Retrieve data from sessionStorage
const tempData = sessionStorage.getItem("tempData");

// Remove data from sessionStorage
sessionStorage.removeItem("tempData");

In short, localStorage is your go-to for long-term storage, while sessionStorage has your back for short-term needs.

#30. What are some common performance optimization techniques for JavaScript, and why would you want to use them?

JavaScript is an amazing language that adds dynamic interactivity to web applications, creating truly engaging experiences. However, it's important to optimize JavaScript code to avoid performance issues, such as slow page load times and unresponsive user interfaces.

The good news is, there are plenty of performance optimization techniques for JavaScript to ensure a silky-smooth experience:

  • Minification: Make your code lean and mean by stripping away unnecessary characters and whitespace. This results in faster downloads and snappy load times

  • Bundling: Merge multiple JavaScript files into one, cutting down HTTP requests and reducing your code's overall size for a performance boost

  • Caching: Store JavaScript files in the browser's cache, enabling reuse on subsequent page loads. This significantly speeds up load times, especially for those returning visitors

  • Lazy loading: Wait to load JavaScript files until they're truly needed, rather than loading everything upfront. This helps cut down initial load time and delights users with a seamless experience

  • Code optimization: Fine-tune your JavaScript code to get even more performance gains. Techniques include reducing variable count, minimizing loop usage, and avoiding costly operations like DOM manipulation

  • Event delegation: Attach event listeners to parent elements instead of individual child elements. This helps keep the number of event listeners in check, giving your application a performance edge

  • Throttling and debouncing: Keep function execution rates in check with throttling and debouncing. Throttling limits the frequency of function calls, while debouncing delays execution until a specified time has passed since the last call. These techniques help improve performance by cutting down on unnecessary function calls

So how did you do?

So there you have it - 30 of the most common JavaScript interview questions that you might face during a frontend developer interview.

Did you answer all 30 correctly? Congratulations! You’re ready to ace that interview.

Or did you struggle with some of them? If you knew the answers but forgot, just give yourself some time to recap before the interview.

Or did none of this make sense?

Not a problem either. As I mentioned earlier, Zero To Mastery has 3 JavaScript courses that can help you up your skills and advanced JS knowledge, so that you blow away any interview questions.

Heck… we even have detailed resources on how to ace the technical interview, how to get hired at FAANG, and even how to get through the door and wow them with your projects!

You’ll not only get access to step-by-step tutorials, but you can ask questions from me and other instructors, as well as other students inside our private Discord.

ztm private discord

Either way, if you decide to join or not, good luck with your interview and go get that job!

More from Zero To Mastery

[Guide] Computer Science For Beginners preview
[Guide] Computer Science For Beginners

You DO NOT need a CS Degree to get hired as a Developer. Learn Computer Sciences Basics today with this free guide by a Senior Dev with 10+ years of experience.

Top 9 Beginner JavaScript Practice Projects (Yes, Code Included!) preview
Top 9 Beginner JavaScript Practice Projects (Yes, Code Included!)

Hey Web Dev - do you want to sharpen your JavaScript skills? Then come join me and let's start building some awesome beginner friendly JavaScript projects to boost your portfolio & skills.

Understand How Javascript Closures Work with Simple Examples preview
Understand How Javascript Closures Work with Simple Examples

Learning how closures work will with simple examples and real-world cases will make your life a lot easier and save you stress when solving daily problems.