upGrad KnowledgeHut SkillFest Sale!

Front End Developer Interview Questions and Answers

The process of creating the visual elements that users see and interact with within a web application is known as front-end development. The frontend developer is responsible for creating a web application. This guide will help you to gain confidence and knowledge about front end development, no matter if you're a beginner, intermediate, or experienced frontend professional. This course covers a variety of HTML5, CSS3, JS, and React JS questions at a basic through advanced level. So, if you are looking to advance your career in a Front-end developer, this guide is the perfect resource for you. Don't wait any longer, start preparing for your interview today! Check out this list of top, expert-curated Front end Developer interview questions and answers to help you pass interviews related to Frontend development. Take advantage of these technical interview questions and answers to ace your next job interviews in big organizations.

  • 4.7 Rating
  • 30 Question(s)
  • 68 Mins of Read
  • 8058 Reader(s)

Filter By

Clear all

Beginner

In JavaScript, event capturing and event bubbling is two different ways that events can propagate through the Document Object Model (DOM). Event capturing is the process by which an event travels from the top of the DOM down to the target element, while event bubbling is the process by which an event travels from the target element up to the top of the DOM.

Both event capturing and event bubbling allow you to attach multiple event listeners to a single element and control the order in which they are executed. This can be useful for creating complex event-driven applications.

Here is an example of how event capturing and event bubbling work:

<div id="outer"> 
<div id="inner"><button>Click me</button></div> 
</div>  

In this example, the button is the target element. If the button is clicked, the event will first be captured by the inner element, then by the outer element.

If we attach an event listener to the outer element using the addEventListener method and set the useCapture option to true, the event will be captured by the outer element first and then trickle down to the inner element.

This is an example of event capturing.

 document.getElementById('outer').addEventListener('click', function(event) { 
console.log('Outer element clicked'); 
 }, true); 

This is one of the most frequently asked Front-end interview questions.  

JavaScript allows us to check the empty state of an object by using the Object.keys() method, which returns an array of the object's own enumerable properties. If the object has no properties, the Object.keys() method will return an empty array. 

We can use the length property of the array returned by Object.keys() to check if the object is empty or not. If the length of the array is 0, the object is empty. 

Here is an example of how to check if an object is empty in JavaScript: 

function isObjectEmpty(obj) { 
   return Object.keys(obj).length === 0; 
} 
var obj = {}; 
console.log(isObjectEmpty(obj));       // Output: true 
obj = { a: 10, b: 12 }; 
console.log(isObjectEmpty(obj));       // Output: false 
 console.log(2 + true); 
 console.log(true + ‘2’); 

In JavaScript, boolean values are treated as numbers when used in arithmetic operations. true is treated as the number 1, and false is treated as the number 0. Therefore, the + operator performs addition and returns the sum of 2 and 1, which is 3. 

In this case, the operands are the boolean value true and the string "2". Since one of the operands is a string, the + operator concatenates them, resulting in the string "true2". 

A callback function in JavaScript is a function that is passed as an argument to another function and is executed after the latter function has completed its execution. Callback functions are commonly used in JavaScript and other programming languages to perform certain actions after an event has occurred or to execute a function asynchronously.  

For example, a callback function may be passed as an argument to an event listener function, which will execute the callback function when the specified event occurs. Callback functions are often used to perform tasks that may take a long time to complete, such as making an HTTP request or reading from a file without blocking the main execution thread.

Expect to come across this, one of the most popular UI developer interview questions.  

CSS selectors are used to select elements on an HTML page and apply styles to them. There are various types of CSS selectors, including element selectors, class selectors, and ID selectors, which can be used to select elements based on their tag name, class name, or ID, respectively. 

Some examples of CSS selectors: 

  • Element selector: Selects all elements with a specific tag name. For example, the element selector "p" would select all paragraph elements on the page. 
  • Class selector: Selects all elements with a specific class name. Class selectors are denoted by a period (.) followed by the class name. For example, the class selector ".error" would select all elements with the class "error". 
  • ID selector: Selects a single element with a specific ID. ID selectors are denoted by a hash symbol (#) followed by the ID. For example, the ID selector "#header" would select the element with the ID "header". 

Here are the differences -

Block elements: 

  • Take up the entire width of their parent container. 
  • Adds a new line after them 
  • Specific Dimensions (such as width and height) can be specified. 
  • Eg. <p>, <section>, <nav> etc. 

Inline elements: 

  • Takes up the necessary width as per content. 
  • Do not add a new line after them 
  • Specific Dimensions (such as width and height) cannot be specified. 
  • Eg. <span>, <a> 

Inline-block elements: 

  • Takes up the necessary width as per content. 
  • Adds a new line after them 
  • It is possible to Specify Dimensions (such as width and height). 
  • Eg. <img>, <input> 

A must-know for anyone heading into a Front-end developer interview, this is one of the most frequently asked Front-end developer questions.

The visibility property specifies whether an element is visible or not. When an element's visibility is set to hide, the element is still present in the HTML code, but is not visible to the user. This means that the element takes up the required space on the page but is not visible.

The display property specifies how an element should be displayed on the page. When an element's display is set to none, the element is not present in the layout of the page at all. This means that the element does not take up any space on the page and is not visible to the user.

Expect to come across front-end developer questions on this topic more often than others.

The practise of making website or web application accessible to the disabled users is known as web accessibility. The term encompasses people who are blind, deaf, or who have limited mobility or cognitive abilities. The four guiding principles of web accessibility must be closely followed to ensure solid web accessibility i.e.  

  • Perceivable 
  • Operable 
  • Understandable 
  • Robust 

Below are a few examples of how web accessibility can be implemented on a website: 

  1. Providing alternative text (alt text) for images 
  2. Providing captions and transcripts for videos. 
  3. Using proper color contrast. 
  4. Adding keyboard navigation. 
  5. Using descriptive headings and subheadings. 

By using float CSS property, elements are placed on either left or right sides of their container, allowing text and inline elements to wrap around them. When an element is set to float, it is removed from the normal flow of the document and positioned to the left or right of its parent element. 

img { 
float: left; 
width: 50%; 
} 

In this example, the float property is set to left and the width property is set to 50%. This will cause the image to float to the left of its parent element and take up 50% of the available width. The text on the page will then wrap around the image.

This reverseString function takes a string as an argument and uses the split(), reverse(), and join() methods to reverse it. 

  • The split() method is used to split the string into an array of individual characters.  
  • A reverse() method reverses the order of the array elements.  
  • The join() method is used to join the elements of the array back into a single string. 
function reverseString(str) { 
return str.split('').reverse().join(''); 
} 
let reversed = reverseString("hello"); 
console.log(reversed); // outputs "olleh"

Array destructuring is a way to extract elements from an array and assign them to variables in a concise and convenient way. It is a feature in JS that allows you to extract multiple values from an array and assign them to individual variables with a single assignment statement. 

let colors = ["red", "green", "blue"]; 
let [first, second, third] = colors; 
console.log(first, second, third); // outputs red green blue 

As the number of callback functions increases, the program's code can become difficult to understand and manage, leading to what is known as "callback hell". Callback hell can occur when a program relies heavily on asynchronous function calls that require the use of callback functions to handle their results.

To avoid callback hell, it is often recommended to use more modern approaches to asynchronous programming, such as promises or async/await, which can help to make the code more readable and easier to maintain.

The Fibonacci series function uses a recursive approach to calculate the nth number in the series. The function calls itself with n - 1 and n - 2 as arguments until it reaches the base case, at which point it returns the value of n. 

function fibonacci(n) { 
if (n <= 1) { 
return n; 
} 
return fibonacci(n - 1) + fibonacci(n - 2); 
} 
console.log(fibonacci(10)); // outputs 55 

The clearfix is used to clear floating elements from the flow of a web page. It is often used when a container element contains floating child elements and the container element's height is not being expanded to enclose the floating elements. 

One way to implement clearfix technique is to use the :after pseudo-element to create a new element that is inserted after the container element.  

.container:after { 
content: ""; 
display: table; 
clear: both; 
} 

In this example,  

  • :after pseudo-element is used to create a new element after the .container element.  
  • The clear property is set to both, which prevents the element from floating and clears any floating elements on both sides of the container element.  
  • The display property is set to table, which causes the element to behave like a table cell, and the content property is set to an empty string, which creates the element without adding any content.

Semantics tags are the elements that have a certain meaning. Even if you are not from the technical background, you are able to understand the meaning of those tags. In short, HTML elements that clearly describe their meaning in a human-and machine-readable way are semantic. Both browsers and developers can clearly understand its meaning. 

HTML5 has introduced many semantic elements. Some of them are: 

  • <article>: Defines an article 
  • <footer>: Defines a footer for some document/ section 
  • <section>: Defines a section  
  • <header>: used for some headings/ headers in a document 
  • <nav>: Used for navigation links 

Meta tags are fragments of code that tell search engines important information about your webpage, such as how they should post it in the search result. All web pages have meta tags placed in the head section, but they are only visible in HTML code. Search engine rankings and click-through rates are affected by meta tags because they determine how your website appears in search results.  

Example of some meta tags: 

<head> 
<meta name = “description” content = “Tutorials”> 
<meta name = “viewport” content = “width=device-width, initial-scale=1.0”> 
</head> 

The following table compares the different types of storage that are available in browsers. 

Session Storage
Local Storage
Cookies

Since data is only stored for the current session, it will be deleted when the browser is closed. 

Closing the browser does not delete the stored data. 

The expiration time for the data can be specified. 

Data storage capacity: 5MB. 

Data storage capacity: 10MB. 

Data storage capacity: Limited to 4KB. 

  • HTML5 Feature
  • The web application allows users to temporarily store data on their devices. 
  • HTML5 Feature
  • Data can be stored on the device and accessed later, even if the browser is closed. 
  • The oldest and HTML4 well-known mechanism.
  • Allows for storing data on a user's device. 

 Typically used for storing login credentials and other sensitive data. 

Useful for storing preferences or settings you want to persist or for offline data storage. 

Used for storing data that shouldn't be retained for a long time, such as user preferences, and for storing session IDs. 

Data stored on: Browser. 

Data stored on: Browser and system 

Data stored on: Browser. 

Data Sent with request from client to server: No 

Data Sent with request from client to server: No 

Data Sent with request from client to server: Yes 

Some of the common HTML5 APIs are: 

  • Web Storage API 
    • Local and session storage. 
  • HTML5 Geolocation API  
    • Tool that enables us to determine the geographical position of a device by using GPS data.  
    • When we request permission from the user, the API can provide us with information such as the device's latitude and longitude, altitude in meters, heading direction, speed etc.  
    • The information is obtained through the navigator function. 
  • HTML5 Application Cache API 
    • Allows web applications to run offline by making them accessible without an internet connection.  
    • Creating an offline version of a web application is easy with the application cache, as it requires the creation of a cache manifest file. 
    • The application cache provides several benefits for applications, including offline browsing, faster speed due to locally cached resources, and reduced server load as the browser only downloads updated or changed resources from the server. 
  • HTML5 Web Workers API  
    • Designed to run tasks in the background independently of other user-interface scripts, without impacting the performance of the page.  
    • Means the user and the web page will not be interrupted as the tasks are being executed in the background using a web worker. 

In HTML, it is necessary to include a DOCTYPE declaration. The DOCTYPE is not an element or HTML tag, but rather a directive that tells the browser how to interpret the document. It specifies the version or standard of HTML (or other markup language) that is being used.  

If the DOCTYPE is not included in the HTML document, the browser may enter Quirks mode. In Quirks mode, the behaviour of the browser may vary based on the version of the browser and may not support certain HTML5 tags.

There are several ways to align an element horizontally and vertically in the center of a page or container using CSS: 

  • Using Absolute Positioning and Transform 
.element { 
position: absolute; 
top: 50%; 
left: 50%; 
transform: translate(-50%, -50%); 
} 
  • Using Flexbox 
.container { 
display: flex; 
align-items: center; 
justify-content: center; 
} 
  • Using Grid Layout 
.container { 
display: grid; 
place-items: center; 
} 
  • Using Table Layout 
.container { 
display: grid; 
place-items: center; 
} 
  • Using Text-align and Line-height 
.container { 
text-align: center; 
} 
.element { 
display: inline-block; 
line-height: 100%; 
} 

We can use Flexbox to align all the elements within a single row. To do this, we can create a parent element (such as a <ul> element) and place several child elements (such as <li> elements) inside it. Then, we can set the display property of the parent element to "flex" to align the child elements in a single row.

Here is an example of how we can use CSS and Flexbox to align four elements in the left corner and one element in the right corner of a container/parent:  

 .parent { display: flex; justify-content: space-between; } 
 .parent > *:not(:last-child) { margin-right: auto; } 

The justify-content: space-between property evenly distributes the space between the elements, and the margin-right: auto property pushes the last element to the right corner of the container. 

Note: This code assumes that the elements are direct children of the container element <ul> and are siblings of each other. If the elements are not direct children, you may need to adjust the CSS selector accordingly. 

If we have added a margin of 10px to the bottom of the first paragraph and a margin of 10px to the top of the second paragraph, the total margin will be 10px. This is because the margins are collapsible. In this case, the margin bottom of the first paragraph, and the margin top of the second paragraph will overlap each other resulting in total 10px margin in between not 20px.

The box model is a way of representing the space that an element occupies in a web page. It consists of the element's content, padding, border, and margin. The box model is important to understand when working with CSS because it determines the size and position of elements on a web page. 

  • The content is what is inside the element, such as the text or graphic.  
  • Space which separates the content and the border is known as padding. 
  • Border is a line that surrounds the element and separates it from other elements.  
  • Margin is the space outside of the border, between the element and other elements. 

A variable which is not assigned any value is ‘undefined’. It is the default value of uninitialized variables, function arguments that have not been assigned a value, and properties that do not exist. Example in the below code snippet, y and typeof y both are undefined as variable y is not assigned any value.  

let y;
console.log(y); / /undefined
console.log(typeof y) // undefined 

Null means nothing. We can assign a variable with a null value. Example:  

let y = null;
console.log(y); //null
console.log(typeOf x) //object. 

Undefined is a property of the global object, while null is a primitive value. For example, the expression typeof undefined will return "undefined", while the expression typeof null will return "object". 

The onload and onloadstart events are both events that can be used in web development to trigger actions when a resource has finished loading. Despite these similarities, there are some important differences. 

Onload Event 

  • is an event that is fired when a resource has finished loading.  
  • This can be used to trigger actions when an image, script, or other resource has finished loading.  
  • The onload event is often used to ensure that certain actions are not performed until a resource has finished loading. 

Onloadstart Event 

  • is an event that is fired when a resource begins to load.  
  • This can be used to trigger actions when an image, script, or other resource begins to load.  
  • The onloadstart event is often used to display a loading indicator or to perform other actions while a resource is loading. 

Difference between the two events is that onload is fired for all resources, while onloadstart is only fired for the first resource in the document. This means that onload can be used to track the loading of multiple resources, while onloadstart is only fired once when the document begins to load. 

In JavaScript, the forEach and map array methods are both used to iterate over the elements of an array and perform an operation on each element. Nevertheless, there are some significant differences between them. 

The forEach method is used to iterate over an array and perform a function on each element. It does not return a new array and modify the original array. However, unlike forEach, map returns a new array that contains the modified elements. The map method is often used when you want to transform the elements of an array and create a new array with the modified elements. 

Here is an example of how we can use the forEach and map methods: 

const arrayNum = [1, 2, 3, 4, 5]; 
// Using forEach 
arrayNum.forEach(el => console.log(el * 2)); 
// Using map 
const numDouble = arrayNum.map(el => el * 2); 
console.log(numDouble); // [2, 4, 6, 8, 10] 

Variables are declared with let and var in JavaScript. Let and var differ primarily in their scope. A let declaration is block-scoped and is not hoisted, whereas a var declaration is globally or function-scoped and is hoisted. Variables declared as var can be accessed throughout the script or function, whereas variables declared as let can only be accessed within their own block of code. For example: 

 if (true) { 
var x = 10; 
let y = 20; 
 } 
 console.log(x); // 10 
 console.log(y); // Uncaught ReferenceError: y is not defined 

In this example, the var variable x is accessible outside of the block in which it is declared, while the let variable y is not. 

Another difference between let and var is that let declarations are not hoisted to the top of the script or the top of the function, like var declarations are. This means that we cannot use a let variable before it has been declared. 

console.log(x); // Uncaught ReferenceError: x is not defined 
let x = 10; 

In this example, an error is thrown because x has not been declared before it is used. This is not the case with var declarations, which are hoisted to the top of the script or function. 

console.log(x); // undefined 
var x = 10; 

In this example, x is hoisted to the top of the script, so the console.log statement does not throw an error. However, the value of x is undefined, because the declaration has not yet been initialized. 

In JavaScript, we can create an object in several ways.  

  • Object Constructor Function: This creates an empty object.  
 const obj = new Object(); 
  • Object Literal Syntax: This creates an object with some properties and values. 
 const obj = { 
key1: 'value1', 
key2: 'value2' 
 }; 
  • Object.create() Method: The object is created as an instance of the object passed to the Object.create() method. 
 const obj = Object.create({ 
key1: 'value1', 
key2: 'value2' 
}); 
  • Class: A class is a template for an object that defines its properties and methods. To create an object using a class, you first define the class, then use the new keyword to create an instance of the class: 
class MyClass {  
constructor(key1, key2) { 
this.key1 = key1; 
this.key2 = key2; 
} 
} 
const obj = new MyClass('value1', 'value2'); 

The interviewer can also ask you to open any editor so he could see your programming skills.  

Intermediate

The factorial function uses a recursive approach to calculate the factorial of a given number. It returns n * factorial(n - 1) until it reaches the base case, at which point it returns 1. 

function factorial(n) { 
if (n === 0) { 
return 1; 
} 
return n * factorial(n - 1); 
} 
console.log(factorial(5)); // outputs 120 

Below are some intermediate level interview questions that will help you prepare well. 

When we clone an object in JavaScript, we can either create a deep copy or a shallow copy.

Shallow Copy: A shallow copy of the referenced object is created when a reference variable is copied into a new reference variable using the assignment operator. An old reference variable's value is assigned to a new reference variable by copying its address. As a result, both the old and new reference variables refer to the same object in memory. Therefore, if any one of the reference variables changes, it will affect both.

// Code Snippet for Shallow Copy 
var employee = { 
  ename: "abc", 
  salary: 50000 
} 
console.log(employee);                                   // {ename: “abc”, salary: “5000”} 
var newEmployee = employee;                      // Shallow copy 
console.log(newEmployee);                          // {ename: “abc”, salary: “5000”} 
newEmployee.ename = "xyz"; 
console.log(employee);                                  // {ename: “xyz”, salary: “5000”} 
console.log(newEmployee);                          // {ename: “xyz”, salary: “5000”} 
// ename of employee and newEmployee both are changed. 

Deep Copy: In contrast to shallow copies, deep copies make copies of all the members of an object, allocate separate memory locations for the new object, and then assign the copied members to it. Hence, both the objects are independent from one another and any changes to either one will not affect the other. JSON.parse() and JSON.stringify() allow us to deep copy objects in JavaScript.  

When the object has serializable properties and is small, this method is useful. However, if the object is very large and contains certain non-serializable properties, data loss may occur. So, CloneDeep() Method from Lodash library is the better way to deep clone the object. 

A common occurrence in Front-end developer questions, don't miss this one.

One of the most frequently posed junior Front-end developer interview questions, be ready for it.  

Arrow functions are a shorthand syntax for defining functions in JavaScript. They are similar to regular functions but have a shorter syntax and some differences in behaviour. 

One of the main benefits of using arrow functions is that they can help reduce the amount of code we need to write.  

For example, we can define a function with a single statement and no function keyword or curly braces: 

const add = (a, b) => a + b; 
This is equivalent to: 
const add = function(a, b) { 
return a + b; 
}; 

Arrow functions also have a lexical this value, which means that this value inside the function is the same as the value outside the function. This can be useful when we need to access this inside a callback function, For example; 

const obj = { 
message: 'Hello', 
sayHello: () => { 
console.log(this.message); 
} 
}; 
obj.sayHello(); // logs "Hello" 

This is different from regular functions, where the value of this is determined by how the function is called. 

A pure function is a function that has the following properties: 

  • It only depends on its input arguments and doesn't have any side effects. This means that it doesn't modify any external state, such as global variables or the properties of objects that are passed to it as arguments. 
  • If the input arguments remain the same, it will produce the same output. This means that it doesn't depend on any external state and is deterministic. 
  • It doesn't produce any observable side effects. This means that it doesn't perform any actions that have visible effects outside the function, such as printing to the console or updating the DOM. 

Pure functions have several benefits: 

  • They are easier to understand as their behaviour is fully determined by their input arguments and they don't have any hidden side effects. 
  • They are easier to test, because you only need to verify that the output is correct for a given set of input arguments, without worrying about any external state. 
  • They are easier to reuse and compose, because they don't depend on any external state and can be easily combined with other functions to create new functionality. 
  • They can improve the performance of your code, because they can be optimized and cached by the runtime, since they always produce the same output for the same input arguments. 

It is generally a good idea to write pure functions whenever possible, as they can help to make your code more predictable, maintainable, and efficient. 

A staple in Front-end interview questions and answers, be prepared to answer this one.  

A closure is a function that has access to the variables in its lexical scope, even when it is executed outside of that scope. Closures are created every time a function is defined inside another function. The inner function has access to the variables and parameters of the outer function, even after the outer function has returned. 

Example: 

function outerFunction(x) { 
let y = x; 
function innerFunction() {  
console.log(y)  
} 
return innerFunction; 
} 
const myClosure = outerFunction(5); 
myClosure(); // logs 5 

In this example, the innerFunction has access to the y variable, even though it is defined and executed outside the outerFunction. This is because innerFunction is a closure that has access to the variables in its lexical scope. 

Closures are often used to create private variables and functions that can only be accessed from within a specific scope. They can also be used to keep track of the state and create callback functions that have access to that state. 

Overall, closures are an important and powerful concept in JavaScript, and they are often used to create more modular and maintainable code. 

In JavaScript, hoisting is the behaviour of moving declarations to the top of the current scope. This means that declarations of variables and functions are automatically moved to the top of their containing scope, regardless of where they appear in the code. 

For example, consider the following code: 

 console.log(x);          //undefined 
 var x = 5; 

Even though the declaration of the x variable appears after the first line of code, the x variable is actually defined at the top of the current scope (in this case, the global scope). This means that the first line of code will output undefined, rather than throwing a reference error. 

Hoisting only affects declarations, not assignments. This means that the following code will throw a reference error, because the assignment to x is not hoisted: 

   console.log(x);           // Uncaught ReferenceError: x is not defined 
   x = 5; 

Overall, hoisting is an important concept to understand in JavaScript, as it can affect the way your code is executed and can lead to some subtle bugs if you're not careful. 

In JavaScript, the spread operator (represented by three dots: "...") allows you to expand or "spread" an iterable object (such as an array or string) into individual elements. It can be used in a variety of ways, including in function calls, array literals, and object literals. 

Here are a few examples of how the spread operator can be used: 

  • In function calls: 

let numbers = [1, 2, 3, 4]; 
// Without spread operator 
Math.max(numbers);        // Returns NaN (not a number) 
// With spread operator 
Math.max(...numbers);       // Returns 4 
  • In array literals: 

let array1 = [1, 2, 3]; 
let array2 = [4, 5, 6]; 
// Without spread operator 
let combined = [array1, array2];                 // [[1, 2, 3], [4, 5, 6]] 
// With spread operator 
let combined = [...array1, ...array2];             // [1, 2, 3, 4, 5, 6] 
  • In object literals (when used in combination with the "Object.assign" function): 

let obj1 = { a: 5, b: 10 }; 
let obj2 = { c: 3, d: 4 }; 
// Without spread operator 
let merged = Object.assign(obj1, obj2);          // { a: 5, b: 10, c: 3, d: 4 } 
// With spread operator 
let merged = { ...obj1, ...obj2 };                       // { a: 5, b: 10, c: 3, d: 4 } 

The rest operator (also represented by three dots: "...") is like the spread operator, but it works in the opposite direction. It allows you to "gather" or condense multiple elements into a single element. It is primarily used in function parameter lists to represent an indefinite number of arguments as an array. 

Below is an example of how the rest operator can be used: 

function sum(...numbers) { 
  let result = 0; 
  for (const number of numbers) { 
    result += number; 
  } 
  return result; 
} 
console.log(sum(1, 2, 3, 4, 5));  // 15 

In JavaScript, this keyword refers to the object that is currently executing the code. In different contexts, this Keyword might have a different value. 

Below are a few examples of how this keyword can be used in JavaScript: 

  • In a global context (outside of any function), this refers to the global object (usually a window in a web browser). 

Console.log(this);            //Outputs the global object (usually ‘window’) 
  • When calling a function, this is the object that is called the function. 

const person = { 
  name: 'John', 
  greet: function({  console.log(`Hello, my name is ${this.name}`); } 
}; 
person.greet();        // Outputs "Hello, my name is John" 
  • In a constructor function (a function used to create objects), this refers to the object being created. 

function Person(name) { 
  this.name = name; 
  this.greet = function() { 
    console.log(`Hello, my name is ${this.name}`); 
  }; 
} 
const john = new Person('John'); 
john.greet();         // Outputs "Hello, my name is John" 

Front-end development interview questions like this are posed to test your coding skills, be ready to tackle it.  

To focus an input element on a web page when the user clicks on the corner of the page without using JavaScript, you can use the :target pseudo-class in CSS. 

Here is an example: 

  • Create a link element that will be used to trigger the focus event when clicked. This link should point to an element with an ID that corresponds to the input element you want to focus. 
  • Create the input element and give it an ID that matches the href of the link element. 
  • Use the :target pseudo-class to specify the styles for the input element when it is targeted by the link element. In this case, we can use the :focus pseudo-class to style the input element when it is focused. 
  <a href="#input1">Click here to focus input</a> 
  <input type="text" id="input1"> 
  #input1:target:focus { 
       /* styles for the input element when it is targeted and focused */ 
  } 

When the user clicks on the link element, the input element will be targeted and focused, and the styles specified in the :target:focus rule will be applied to it. 

To find the kth closest element to a particular value in an array, we can use the following approach: 

  1. Sort the array in ascending order. 
  2. Find the index of the value in the sorted array using the Array.prototype.indexOf() method. 
  3. If the value is not found in the array, return null. 
  4. If the value is found, return the element at index k from the value's index else return null. 
function findKthClosest(array, value, k) { 
  const sortedArray = array.sort((a, b) => a - b); 
  const index = sortedArray.indexOf(value); 
  if (index === -1) { 
    return null; 
  } 
  return sortedArray[index + k] || null; 
} 
 
const array = [1, 3, 5, 7, 9]; 
const value = 5; 
const k = 2; 
const result = findKthClosest(array, value, k); 
console.log(result); // 7 

Let us now move up the ladder from intermediate to advanced. Listed below are a few interview questions for senior front end developers. 

In React, data is passed from a parent component to a child component through props, which are short for "properties." 

Props are a way for a parent component to pass data to its children, and for the children to receive and use that data. Props are passed to a child component as an object, and the child component can access the data within the object using the this.props property. 

Here is an example of how a parent component might pass data to a child component using props: 

import React from 'react'; 
// Parent component 
class Parent extends React.Component { 
render() { 
return ( 
<Child name="John" age={30} /> 
); 
} 
} 
// Child component 
class Child extends React.Component { 
render() { 
return ( 
<p>Hello, my name is {this.props.name} and I am {this.props.age} years old.</p> 
); 
} 
} 

It is important to note that props are read-only, meaning that a child component cannot modify its props. If a child component needs to modify data that was passed to it via props, it should communicate this back to the parent component, which can then pass the updated data back down to the child via props. This is known as "props drilling" 

One way for a child component to pass data back to its parent component is by using a callback function. A callback function is a function that is passed as a prop to the child component, and it is called by the child component when it needs to pass data back to the parent.

import React from 'react'; 
// Parent component 
class Parent extends React.Component { 
// Define a callback function that will be passed to the child component 
handleDataFromChild(data) { 
// Do something with the data passed from the child component 
} 
render() { 
return ( 
<Child onDataFromChild={this.handleDataFromChild} /> 
); 
} 
} 
// Child component 
class Child extends React.Component { 
// When the child component needs to pass data back to the parent, it calls the callback function 
handleButtonClick() { 
this.props.onDataFromChild({ some: 'data' }); 
} 
render() { 
return ( 
<button onClick={this.handleButtonClick}>Send data to parent</button> 
); 
} 
} 

In this example, the parent component defines a callback function called handleDataFromChild, which it passes to the child component as a prop. The child component can then call this callback function whenever it needs to pass data back to the parent. 

Another way for a child component to communicate data back to its parent is by using the React context API, or by using a state management library like Redux, which are typically only needed in larger applications with complex data flows and may not be necessary for smaller or simpler applications. 

This is one of the frequently asked Front-end interview questions.

It is generally not recommended to call setState inside the render method of a React component. This is because render is called every time the component's state or props are updated, and calling setState inside render can cause an infinite loop.

For example, consider the following component: 

class MyComponent extends React.Component { 
state = { 
count: 0, 
}; 
render() { 
this.setState({ count: this.state.count + 1 }); // Don't do this! 
return <div>{this.state.count}</div>; 
} 
} 

In this component, render is called every time the component's state is updated. However, inside the render method, we are calling setState, which updates the state and triggers another call to render. This creates an infinite loop, causing the component to re-render constantly without ever stopping. 

To avoid this issue, it is generally recommended to avoid calling setState inside the render method. Instead, setState should be called in response to user interactions like (clicking a button) or other events that trigger a state update. 

Expect to come across this, one of the most popular front-end interview questions.  

In a React application, a saga is a piece of code that is responsible for managing side effects. Side effects are actions that have an impact outside of the application, such as making a network request or interacting with a database. 

Sagas are needed in React applications because side effects can often be complex and hard to manage, especially when they involve multiple steps or need to be coordinated with other actions in the application. By encapsulating side effects in a separate piece of code, called a saga, it becomes easier to manage and maintain the application. 

Sagas are implemented using a library called redux saga, which is a middleware that sits between the React application and the Redux store. Redux-saga uses a combination of generator functions and an event-loop to manage side effects in a declarative and efficient way. 

Below is an example of a simple saga that listens for a FETCH_USER action and makes a network request to fetch the user data: 

import { takeEvery, call, put } from 'redux-saga/effects'; 
import api from '../api'; 
function* fetchUser(action) { 
try { 
const user = yield call(api.fetchUser, action.payload.userId); 
yield put({ type: 'FETCH_USER_SUCCESS', user }); 
} catch (error) { 
yield put({ type: 'FETCH_USER_ERROR', error }); 
} 
} 
function* watchFetchUser() { 
yield takeEvery('FETCH_USER', fetchUser); 
} 
export default watchFetchUser; 

A reducer in Redux is a pure function that takes in the current state of the application, an action, and returns the next state of the application. There are no side effects associated with a pure function since it always returns the same output from the same input.  

There are a few reasons why reducers are designed to be pure functions: 

  • Predictability: Because a reducer is a pure function, it is easy to predict what the next stage of the application will be based on the current state and the action. This makes it easier to reason about the behavior of the application and to write tests for the reducer. 
  • Consistency: Because a reducer does not have side effects, it does not rely on external factors or mutate the state in an unpredictable way. This makes the behavior of the reducer more consistent and easier to understand. 
  • Performance: Because a reducer is a pure function, it can be easily optimized by the JavaScript runtime. For example, the runtime can cache the results of the reducer and avoid recomputing them if the input does not change. 

A must-know for anyone heading into the technical interview, this is one of the most frequently asked UI developer questions.

Redux is a state management library that is often used in React applications. It provides a simple and predictable way to manage the state of the application and to update the state in response to actions.

The basic flow of Redux can be summarized as follows: 

  1. An action is dispatched: An action is an object that describes an event that has occurred in the application. It typically includes a type field that describes the type of event that has occurred and may also include additional data payload. 
  2. The reducer processes the action: The reducer is a pure function that takes in the current state of the application and the action and returns the next state of the application. It is responsible for updating the state based on the action. 
  3. The store updates the state: A store is an object that holds the current state of the application and provides methods for accessing and updating the state. When the reducer returns the next state, the store updates its internal state to match the new state. 
  4. The component re-renders: If the component is connected to the store using the react-redux library, it will be notified of the state change and re-render to reflect the updated state. 

Here is a simple example of a Redux flow in a React application: 

// Action 
const action = { 
type: 'ADD_TODO', 
payload: { 
text: 'Learn Redux' 
} 
}; 
// Reducer 
function reducer(state, action) { 
switch (action.type) { 
case 'ADD_TODO': 
return { 
...state, 
todos: [...state.todos, { text: action.payload.text }] 
}; 
default: 
return state; 
} 
} 
// Store 
const store = createStore(reducer, { todos: [] }); 
// Component 
class TodoList extends React.Component { 
render() { 
const { todos } = this.props; 
return ( 
<ul> 
{todos.map(todo => ( 
<li key={todo.text}>{todo.text}</li> 
))} 
</ul> 
); 
} 
} 
const mapStateToProps = state => ({ 
todos: state.todos 
}); 
const ConnectedTodoList = connect(mapStateToProps)(TodoList); 
// Dispatch action 
store.dispatch(action); 

In this example, the ADD_TODO action is dispatched when the user clicks a button. The reducer processes the action and updates the todos array in the state. The store updates its internal state and the TodoList component re-renders to display the updated list of todos.

Redux flow is one of the most mentioned topics among Front-end developer questions, so make sure you master this topic as well.

In React, the lifecycle of a component refers to the different stages of its existence, from the moment it is created to the moment it is destroyed. In the past, React provided a set of lifecycle methods that could be used to manage the lifecycle of a component, such as componentDidMount, componentDidUpdate, and componentWillUnmount. 

Starting from React 16.8, it is also possible to manage the lifecycle of a component using hooks. Hooks are functions that allow you to use state and other React features in functional components. 

Below is an example of how to use the useEffect hook to manage the lifecycle of a component: 

import { useEffect } from 'react'; 
function MyComponent() { 
useEffect(() => { 
// componentDidMount and componentDidUpdate 
return () => { 
// componentWillUnmount 
}; 
}); 
return <div>My component</div>; 
} 

The useEffect hook takes a callback function as an argument, which will be called after the component is rendered. The callback function can perform side effects, such as making a network request or setting up an event listener. 

The useEffect hook can also accept a second argument, which is an array of dependencies. If the dependencies change, the callback function will be called again. This allows you to specify when the effect should be run. If the array is empty, the effect will only be run once, when the component is mounted. 

Here is an example of how to use the useEffect hook with dependencies: 

import { useEffect, useState } from 'react'; 
function MyComponent() { 
const [count, setCount] = useState(0); 
useEffect(() => { 
console.log(`Count is ${count}`); 
// componentDidUpdate 
}, [count]); // Only re-run the effect if count changes 
return ( 
<div> 
<button onClick={() => setCount(count + 1)}>Increment</button> 
</div> 
); 
} 

In React, the setState method is used to update the state of a component. It takes two arguments: the first argument is an object that specifies the state changes to be made, and the second argument is a callback function that will be called after the state has been updated. 

Here is an example of how to use setState with a callback function: 

class MyComponent extends React.Component { 
constructor(props) { 
super(props); 
this.state = { count: 0 }; 
} 
incrementCount = () => { 
this.setState({ count: this.state.count + 1 }, () => { 
console.log(`Count is now ${this.state.count}`); 
}); 
}; 
render() { 
return ( 
<div> 
<button onClick={this.incrementCount}>Increment</button> 
</div> 
); 
} 
} 

In this example, the incrementCount method updates the count state variable and logs the new value to the console using a callback function. The callback function is called after the state has been updated and the component has re-rendered. 

The second argument to setState is optional, and you can omit it if you do not need to perform any actions after the state has been updated. 

In a React application, a controlled component is a component that is controlled by the React state. This means that the component's value and behavior are determined by the state, and the component does not maintain its own internal state. 

An uncontrolled component, on the other hand, is a component that maintains its own internal state. The value of the component is not controlled by the React state, and the component can update its own value independently of the React state. 

Below is an example of a controlled text input component: 

class ControlledInput extends React.Component { 
constructor(props) { 
super(props); 
this.state = { value: '' }; 
} 
handleChange = event => { 
this.setState({ value: event.target.value }); 
}; 
render() { 
return ( 
<input 
type="text" 
value={this.state.value} 
onChange={this.handleChange} 
/> 
); 
} 
} 

In this example, the value of the input is controlled by the value state variable, and the onChange event handler is used to update the state when the input value changes. 

Below is an example of an uncontrolled text input component: 

class UncontrolledInput extends React.Component { 
inputRef = React.createRef(); 
handleSubmit = event => { 
event.preventDefault(); 
console.log(this.inputRef.current.value); 
}; 
render() { 
return ( 
<form onSubmit={this.handleSubmit}> 
<input type="text" ref={this.inputRef} /> 
<button type="submit">Submit</button> 
</form> 
); 
} 
} 

In this example, the input does not have a value prop and is not controlled by the React state. Instead, the input's value is accessed directly using the ref system. When the form is submitted, the value of the input is logged to the console using the ref object. 

Controlled components are generally easier to manage and test because the state of the component is fully determined by the React state. Uncontrolled components can be useful when you need to work with a DOM API or when you need to optimize performance by avoiding unnecessary re-renders.

A frequent occurrence in the list of Front-end developer technical interview questions, don't miss this one.

Generator functions are used in sagas because they provide a convenient way to pause and resume the execution of a function. This is useful when working with side effects, because it allows you to perform async operations in a declarative and efficient way.

In a saga, generator functions are used to manage the flow of the saga and to coordinate the execution of async tasks. The redux-saga library provides a set of helper functions, called effects, that can be used to pause the generator function and wait for a specific event to occur.

Advanced

In HTML, a webpage can be displayed in either standards mode or quirks mode. These modes determine how a webpage is rendered by a web browser, and they can affect the way the webpage looks and behaves. 

Standards mode is the preferred mode for rendering webpages, as it follows the standards set by the World Wide Web Consortium (W3C) for HTML, CSS, and other web technologies. When a webpage is displayed in standards mode, the web browser follows the standards specified in the HTML and CSS code, which ensures that the webpage is displayed consistently across different browsers. 

Quirks mode, on the other hand, is a way for web browsers to handle older or improperly coded webpages. When a webpage is displayed in quirks mode, the web browser uses a different set of rules to try to display the webpage correctly. These rules are based on the way web browsers used to handle webpages in the past, and they can cause the webpage to be displayed differently in different browsers. 

To determine which mode to use, web browsers look at the HTML code of the webpage and check for certain tags or attributes that indicate which mode to use.  

For example, if the webpage includes a <!DOCTYPE> declaration at the top of the HTML code, the browser will use standards mode. If the <!DOCTYPE> declaration is missing or incorrect, the browser will use quirks mode. 

Webpack is a module bundler for modern JavaScript applications. It is a powerful tool used by developers to write and organize their code in a modular manner, and then bundle it together into a single file (or a few files) that a web browser can load. 

One of the main benefits of using webpack is that it allows developers to use the latest JavaScript features and syntax, even if the user's web browser does not support those features. Webpack also offers a range of other features and capabilities, such as: 

  • Code Splitting: Allows developers to split their code into smaller chunks that can be loaded on demand, which can improve the performance and load time of their applications. 
  • Asset Management: Allows developers to import and manage various types of assets, such as images, fonts, and stylesheets, and then include them in their code. 
  • Plugins: Allows developers to extend the capabilities of webpack with custom plugins that can perform a wide range of tasks, such as optimizing images or linting code. 
  • Can transpile (convert) modern JavaScript code into a form that is compatible with older browsers, making it easier to write code that works across a wide range of browsers and devices. 

There are several ways to reduce the page load time of a website or web application. Here are a few suggestions:

  1. Optimize Images: Large images can significantly increase the page load time. Compress your images and reduce their file size using tools like ImageOptim or Kraken.io. 
  2. Minimize HTTP Requests: Each time a browser requests a new file (such as an image or stylesheet), it adds to the page load time. To reduce the number of requests, consider combining multiple files into a single file (e.g., combining multiple stylesheets into one) or using a content delivery network (CDN) to host static assets. 
  3. Enable Browser Caching: When a user visits a webpage, the browser stores a copy of the files locally in its cache. This allows the webpage to load faster on subsequent visits. To enable browser caching, add appropriate cache control headers to your server configuration. 
  4. Use a CDN: A CDN is a network of servers that deliver web content based on the geographic location of the user. Using a CDN can reduce the page load time by serving content from a server that is closer to the user. 
  5. Minify and Compress Code: Reducing the size of your HTML, CSS, and JavaScript files can help to improve page load time. Use tools like UglifyJS or cssnano to minify and compress your code. 
  6. Optimize the order of Styles and Scripts: Placing stylesheets at the head of your HTML document and scripts at the bottom of the body can help improve the rendering time of your webpage. 
  7. Use Lazy Loading: Lazy loading allows you to load content as it is needed rather than all at once. This can be especially useful for pages with a lot of content, as it can help to reduce the initial page load time. 

By implementing some or all of these strategies, one can significantly improve the page load time of your website or web application. 

This is one of the frequently asked senior Front-end developer interview questions.  

Dependency injection (DI) is a design pattern that allows an object to receive its dependencies from an external source rather than creating them itself. This can make it easier to design, test, and maintain complex systems, as it allows different components of the system to be isolated from one another and more easily modified or replaced. 

In a DI system, objects are typically defined with interfaces that specify their dependencies. An external source, such as a container or factory, is responsible for creating and injecting the required dependencies into the object when it is needed. This means that the object does not need to know how to create its dependencies, or even what they are. 

For example, consider a simple object that represents a car. The car object might have a dependency on an engine object, which it needs in order to operate. Without DI, the car object might create its own engine object using the new operator, like this: 

class Car { 
constructor() { 
this.engine = new Engine(); 
} 
} 

With DI, the car object would instead define an interface for its engine dependency, and the DI container would be responsible for creating and injecting the engine object when the car object is created: 

class Car { 
constructor(engine) { 
this.engine = engine; 
} 
} 

Using DI has several benefits: 

  • It makes it easier to test and modify the components of a system, as they can be easily swapped out for different implementations. 
  • It can help to reduce the complexity of a system, as objects do not need to know how to create their own dependencies. 
  • It allows different components of a system to be more loosely coupled, as they do not need to know about the implementation details of their dependencies. 

Overall, dependency injection is a useful design pattern that can help to improve the modularity, testability, and maintainability of complex systems.

Lazy loading is a technique that allows content to be loaded on demand, rather than all at once. This can help to improve the performance and load time of a webpage or web application, especially if it has a lot of content. 

Lazy loading can be implemented in various ways, such as: 

  • Loading images, content or other assets as they come into view, rather than loading them all at once. 
  • Loading content in chunks as the user scrolls through the page, rather than loading the entire page at once. 

Server-side rendering (SSR) is a technique that allows a web server to generate and serve HTML for a webpage on demand rather than relying on the client's web browser to generate the HTML. This can be useful in various situations, including: 

  • Improving the Performance and Load Time of the Webpage: By rendering the HTML on the server, the webpage can be served to the client more quickly, as the client's browser does not need to wait for the HTML to be generated and sent from the server. 
  • Improving SEO of the Webpage: Search engines can have difficulty indexing and ranking pages that are generated dynamically on the client's browser. By rendering the HTML on the server, search engines can more easily index the content of the webpage. 
  • Providing a Consistent Experience for Users: Some users may have browsers or devices that do not support modern JavaScript features or frameworks. By rendering the HTML on the server, you can ensure that all users have a consistent experience, regardless of their browser or device.

It's no surprise that this one pops up often in UI developer interviews.

Debouncing and throttling are techniques that can be used to reduce the frequency of function calls in JavaScript. They are often used to improve the performance and efficiency of code that is triggered by events, such as user input or window resizing. 

Debouncing is a technique that delays the execution of a function until a certain amount of time has passed without the function being called. This can be useful if you want to ensure that a function is not called too frequently, such as when handling user input events. 

For example, consider a function that is called every time the user types a character into an input field: 

document.querySelector('input').addEventListener('keyup', function() { 
search(); 
}); 
function search() { 
// Perform a search 
} 

If the user types quickly, this function could be called many times in a short period, which could cause performance issues. To address this, we can use debouncing to delay the execution of the function until the user has finished typing: 

let timeout; 
document.querySelector('input').addEventListener('keyup', function() { 
clearTimeout(timeout); 
timeout = setTimeout(search, 500); 
}); 
function search() { 
// Perform a search 
} 

In this example, the search function is called 500 milliseconds (0.5 seconds) after the user stops typing. This helps to ensure that the function is not called too frequently, while still allowing the user to receive timely feedback. 

Throttling is a technique that limits the number of times a function can be called within a certain time period. This can be useful if we want to ensure that a function is not called too frequently, but we still want it to be called at a regular interval. 

For example, consider a function that is called every time the user scrolls the page: 

window.addEventListener('scroll', function() { 
updatePosition(); 
}); 
function updatePosition() { // Update the element position } 

If the user scrolls quickly, this function could be called many times in a short time, which could cause performance issues. To address this, we can use throttling to limit the number of times the function is called: 

let canCall = true; 
window.addEventListener('scroll', function() { 
if (canCall) { 
updatePosition(); 
canCall = false; 
setTimeout(function() { 
canCall = true; 
}, 100); 
} 
}); 
function updatePosition() { 
// Update the position of an element 
} 

In this example, the updatePosition function is called once every 100 milliseconds (0.1 seconds) while the user is scrolling. This helps to ensure that the function is not called too frequently, while still allowing it to be called at a regular interval. 

In JavaScript, currying is a technique that allows a function to be partially applied, or "pre-filled," with some of its arguments. There are several situations where this can be useful, such as: 

  • Creating functions with a fixed set of arguments that can be easily reused. 
  • Abstracting away certain arguments to make a function more flexible and reusable. 
  • Improving the readability and clarity of code by breaking up complex functions into smaller, more focused functions. 

To understand how currying works, consider the following example: 

function add(a, b) { 
return a + b; 
} 

The function returns the sum of two arguments (a and b). To curry this function, we can create a new function that takes one of the arguments and returns a new function that takes the other argument: 

function add(a) { 
return function(b) { 
return a + b; 
} 
} 
const add5 = add(5); 
console.log(add5(10)); // 15 
console.log(add5(20)); // 25 

In this example, the add5 function is a partially applied version of the add function, with an argument pre-filled with the value 5. This allows us to create a new function that can be easily reused to add 5 to any number. 

Currying can be implemented in a variety of ways in JavaScript, and it can be used to create a wide range of reusable and flexible functions. It is a useful technique for improving the modularity, readability, and clarity of code. 

setTimeout is a JavaScript function that allows us to schedule a function to be executed after a specified amount of time has passed. It works by adding a timer to the JavaScript event loop, which is a queue of tasks that are executed by the browser or runtime environment. 

To illustrate how setTimeout works, here is an example: 

console.log('Start'); 
setTimeout(function() { 
console.log('Timeout'); 
}, 1000); 
console.log('End'); 

In this example, the setTimeout function is called with a delay time of 1000 milliseconds (1 second). When this code is executed, the following will happen: 

  1. The console.log('Start') line is executed, which prints "Start" to the console. 
  2. The setTimeout function is called, which adds a timer to the event loop with a delay time of 1000 milliseconds. 
  3. The console.log('End') line is executed, which prints "End" to the console. 
  4. The event loop begins processing tasks. When it reaches the timer that was added by setTimeout, it waits for the delay time to pass. 
  5. After the delay time has passed, the timer's callback function (console.log('Timeout')) is added to the event loop. 
  6. The event loop continues processing tasks and eventually reaches the callback function, which is executed and prints "Timeout" to the console

CSS pre-processors are tools that allow us to write CSS more powerfully and expressively, and then compile it into standard CSS that can be used on a web page.  

There are several reasons why CSS pre-processors like SASS are preferred over plain CSS: 

  • Improved Code Organization and Reuse: SASS allows you to use features like variables, mixins, and functions to organize and reuse code more effectively. This can help to make your CSS more maintainable and scalable. 
  • Enhanced Syntax and Features: SASS offer a more powerful and expressive syntax than plain CSS, with features like nested rules, operators, and control structures. This can make it easier to write and maintain complex stylesheets. 
  • Improved Performance: SASS can help to improve the performance of your stylesheets by allowing you to use techniques like code minification and source maps. 
  • Better Compatibility with Modern Tools: CSS preprocessors is often used in conjunction with modern front-end tools and frameworks, such as webpack, Grunt, and Gulp. This can make it easier to integrate CSS preprocessors into your workflow and use them with other tools and libraries. 

Overall, CSS preprocessors like SASS are preferred over plain CSS because they offer a range of benefits, including improved code organization and reuse, enhanced syntax and features, improved performance, and better compatibility with modern tools. 

Prior to executing the code, we can explain the logic used in the code to the interviewer, namely using a filter method that runs on each element of the array and leaves only entries that pass the given callback function. A callback function checks whether a value has the first occurrence. If not, it must be the same value and will not be copied. This is how unique elements can be extracted from the array. 

 let myArray = ['ac', 12, 'ac', 12, '1']; 
 let uniqueEl = myArray.filter((value, index, el) => el.indexOf(value) === index); 
 console.log(uniqueEl); // unique elements are ['ac', 12, '1'] 

Is there any other way to implement the same? 

Yes, with the help of inbuilt function Set.

let myArray = ['ac', 12, 'ac', 12, '1']; 
let uniqueEl = […new Set(myArray)]; 
console.log(uniqueEl); // unique is ['ac', 12, '1'] 

Afterwards, the interviewer asked me some

 function abc(){
x = 10;
let y = 5;
}
 abc();
console.log(x, y); 

It will return referenceError: y is not defined, as y is block scoped, and we're trying to access it outside that scope. 

A staple in Front-end developer interview questions, be prepared to answer this one.  

  1. console.log(20+”2");  
  2. console.log(20-”2");  

The output of first statement is "202". In JavaScript, the + operator is used for both addition and concatenation, depending on the operands. When one of the operands is a string, the + operator performs concatenation, meaning it combines the two operands as strings and returns the resulting string. 

In this case, the operands are the number 20 and the string "2". Since one of the operands is a string, the + operator concatenates them, resulting in the string "202". 

The output of second statement would be 18. The - operator is used for subtraction. When both operands are numbers, the - operator performs subtraction and returns the difference. 

In this case, the operands are the number 20 and the string "2". Since the string "2" can be converted to the number 2, the - operator performs subtraction and returns the difference, which is 18. 

A polyfill is a piece of code that provides a missing functionality in older browsers that do not support that functionality natively. One way to implement a polyfill for the map() method in JavaScript is to use a simple loop to iterate over the elements of the array and call the provided function on each element: 

 if (!Array.prototype.map) { 
Array.prototype.map = function(callback, thisArg) { 
var newArray = []; 
for (var i = 0; i < this.length; i++) { 
newArray.push(callback.call(thisArg, this[i], i, this)); 
} 
return newArray; 
} 
 } 

This polyfill checks if the map() method is not already present on the Array.prototype, and if it is not, it defines the map() method as a function that takes a callback function and an optional thisArg as arguments. The callback function is called on each element of the array, and the resulting values are pushed to a new array, which is then returned. 

for (var i = 0; i < 5; i++) { 
  setTimeout(function() {  
console.log(i);  
}, i * 1000 ); 
} 

In this code, there is a for loop that iterates 5 times, from 0 to 4. For each iteration, the setTimeout() function is called with a callback function that logs the value of i. The value of i that is logged is not the value at the time the setTimeout() function is called, but rather the value of i after the for loop has completed.  

This is because the setTimeout() function is a non-blocking function, and the callback function is not executed until the specified delay has passed. Therefore, the value of i is not captured at the time the setTimeout() function is called, but rather at the time the callback function is executed. By the time the callback function is executed, the for loop has already completed, and the value of i is 5. 

So, Output is  

5 
5 
5 
5 
5 

To log the values of i at the time the setTimeout() function is called, you could use an immediately-invoked function expression (IIFE) to capture the value of i at each iteration of the for loop: 

for (var i = 0; i < 5; i++) { 
(function(x) { 
setTimeout(function() { console.log(x); }, x * 1000 ); 
})(i); 
} 

This will log the values of i at the time the setTimeout() function is called, resulting in the output: 

0 
1 
2 
3 
4 

HTML5 Provides a <iframe> tag to display nested webpages. Example: 

   <iframe src =”url of page you want to embed”> 

In HTML5, headers and footers have specific tags. Instead of using a div with an id, let's use a header footer tag. 

<header>  <h1>Monday Times</h1>  </ header >   
<body>.......</body> 
<footer>  <p>Hello World!</p>  </ footer > 

Modals are pop-up windows or dialog boxes that appear on top of the page. Our first step will be to create an HTML DOM structure and then apply CSS3 styles to it. 

The HTML structure is shown below: 

<div id="modal" class="modal"> 
<div class="modal-content"> 
<span class="close">&times;</span> 
<p>Modal Text..</p> 
</div> 
</div> 

Adding styling to a modal using CSS3. 

.modal { 
position: fixed;  
z-index: 1;  
padding-top: 100px;  
left: 0; 
top: 0; 
width: 100%;  
height: 100%;  
overflow: auto;  
background-color: rgb(0,0,0);  
background-color: rgba(0,0,0,0.4); 
} 
.modal-content { 
background-color: #fff; 
margin: auto; 
padding: 15px; 
border: 1px solid #ccc; 
width: 85%; 
} 
.close { 
color: #aaa; 
float: right; 
font-size: 25px; 
font-weight: 700; 
cursor: pointer; 
} 

Once the coding interview is finished, the interviewer starts with the react front end interview questions. Some of the important questions listed below will help you crack your interview.