Frontend Interview Questions 2024 — Javascript
Lets gather some of the important frontend interview questions on javascript.
- What is an arrow function and how it differs from the regular function?
Answer: Arrow functions in JavaScript are a concise way of writing function expressions. The primary difference between arrow functions and regular functions (function declarations or function expressions) is not just syntax; it also affects the behavior of this
, arguments
, and how they handle context.
The key differences:
- Syntax: Arrow functions have a shorter syntax compared to regular functions.
Normal function syntax:
function example(){
console.log("Hello World!");
};
example();
// "Hello World!"
Arrow function syntax:
const example = ()=>{
console.log("Hello World!");
};
example();
this
Binding: Arrow functions lexically bind thethis
value. It means that they inherit thethis
value from the enclosing lexical context (the context where the function is defined) rather than having their ownthis
value. Regular functions, on the other hand, have theirthis
value determined by how they are called.
example:
// Regular function
const obj1 = {
name: 'Regular Function',
printName: function() {
console.log(this.name);
}
};
// Arrow function
const obj2 = {
name: 'Arrow Function',
printName: () => {
console.log(this.name); // 'this' here refers to the global object, not obj2
}
};
obj1.printName(); // Output: Regular Function
obj2.printName(); // Output: undefined
arguments
object: Arrow functions do not have their ownarguments
object. If you need to access the arguments passed to an arrow function, you would use thearguments
of the enclosing non-arrow function.
example:
function regularFunction() {
const arrowFunc = () => {
console.log(arguments); // accessing arguments of the enclosing regular function
};
arrowFunc();
}
regularFunction(1, 2, 3); // Output: [Arguments] { '0': 1, '1': 2, '2': 3 }
//If there are no arguments passed, arguments object will throw 'ReferenceError'
function regularFunction() {
const arrowFunc = () => {
console.log(arguments); // attempting to access arguments of the enclosing regular function
};
arrowFunc();
}
regularFunction(); // Output: ReferenceError: arguments is not defined
new.target
: Arrow functions do not have their ownnew.target
bindings.new.target
refers to the constructor function itself. This makes them unsuitable for use as constructor functions.
example:
function RegularFunction() {
console.log(new.target); // accessing new.target inside a regular function
}
const ArrowFunction = () => {
console.log(new.target); // accessing new.target inside an arrow function
};
const obj1 = new RegularFunction(); // Output: [Function: RegularFunction]
const obj2 = new ArrowFunction(); // Output: undefined
super
keyword: Arrow functions do not have their ownsuper
binding. They cannot be used as methods in classes that require thesuper
keyword.
example:
class Parent {
constructor() {
this.name = 'Parent';
}
showName() {
console.log(this.name);
}
}
class Child extends Parent {
constructor() {
super();
this.name = 'Child';
}
// Attempting to define a method using an arrow function
// inside a class that requires the use of super
// This will result in a SyntaxError
// because arrow functions do not have their own super binding
// and cannot access the parent class's methods or properties.
// Therefore, they cannot be used as methods in such classes.
showErrorName = () => {
super.showName(); // This will result in an error
}
}
const child = new Child();
child.showErrorName(); // This will cause a SyntaxError
2. Write down code for Call, apply bind (write down the code for one of them)
Using the call
and apply
methods we can invoke the function with the new context.
call method:
- The
call
method is used to invoke a function with a specifiedthis
value and individual arguments passed one by one. - Syntax:
function.call(thisArg, arg1, arg2, ...)
const person = {
college: 'NIT',
year: '2024'
}
function alumniInfo(name){
console.log(`${name} passed in ${this.year} from ${this.college}`)
}
alumniInfo.call(person, 'Vidya');//"Vidya passed in 2024 from NIT"
The
call
method allows you to call a function with a specifiedthis
value and arguments provided individually.
apply method:
- The
apply
method is similar tocall
, but it takes an array or an array-like object as the second argument, where each element of the array corresponds to an argument of the function. - Syntax:
function.apply(thisArg, [arg1, arg2, ...])
const person = {
college: 'NIT',
year: '2024'
}
function alumniInfo(name, age){
console.log(`${name} of age ${age} passed in ${this.year} from ${this.college}`)
}
alumniInfo.apply(person, ['Vidya', '24'])//"Vidya of age 24 passed in 2024 from NIT"
bind method:
bind
is used to create a new function with a fixedthis
context, which can be invoked later.
const person1 = {
college: 'NIT',
year: '2024'
}
function alumniInfo(name, age){
console.log(`${name} of age ${age} passed in ${this.year} from ${this.college}`)
}
const alumniInfoOfJohn= alumniInfo.bind(person1);
alumniInfoOfJohn('John',25); //"John of age 25 passed in 2024 from NIT"
3. ES6 features
4. Write down the code for spread operator, rest operator and Object destructuring?
Spread operator: The spread operator is used to expand elements of an iterable (like an array) into individual elements. It’s particularly useful in function calls or array literals.
note: array into individual elements
// Spread operator in function calls
const numbers = [1, 2, 3];
console.log(...numbers); // Output: 1 2 3
// Spread operator in array literals
const numbers2 = [4, 5, 6];
const combined = [...numbers, ...numbers2];
console.log(combined); // Output: [1, 2, 3, 4, 5, 6]
//example2
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
];
const newUser = { id: 4, name: 'David' };
// Adding a new user without mutating the original array
const updatedUsers = [...users, newUser];
console.log(updatedUsers);
Rest operator: The rest operator collects all remaining elements into an array. It’s useful when you want to handle a variable number of arguments in a function.
note: elements into array
// Rest operator in function parameters
function sum(...nums) {
return nums.reduce((acc, num) => acc + num, 0);
}
console.log(sum(1, 2, 3, 4)); // Output: 10
// Rest operator with destructuring
const [first, ...rest] = [1, 2, 3, 4];
console.log(first); // Output: 1
console.log(rest); // Output: [2, 3, 4]
Object destructing: Object destructuring allows to extract properties from objects and bind them to variables.
const person = {
firstName: 'Marry',
lastName: 'Chom',
age: 30
};
const {firstName, lastName} = person;
console.log(firstName, lastName);//"Marry", "Chom"
console.log(`${firstName} ${lastName}`);//"Marry Chom"
// Renaming variables during destructuring
const { firstName: fName, lastName: lName } = person;
console.log(fName, lName); // Output: "Marry", "Chom"
5. Difference between forEach and map?
forEach() and map() are two methods of an array in javascript, but they serve different purpose. Lets list out those points as below:
forEach() :
- It iterates over each element of the array and the callback function perform operation on each element but it doesn’t create the new result array
const numbers = [1, 2, 3, 4];
numbers.forEach((num) => {
console.log(num * 2); // Output: 2, 4, 6, 8
});
map():
- It allows to iterate over each element of the array and the callback function perform operation on each element but it returns a new array containing the results of applying the callback function to each element.
- It’s useful when we want to transform each element of an array into something else and collect the results in a new array without mutating the original array.
const numbers = [1, 2, 3, 4];
const doubledNumbers = numbers.map((num) => {
return num * 2;
});
console.log(doubledNumbers); // Output: [2, 4, 6, 8]
6. Difference between Object.assign(), Object.create()? Which one mutates the data ?
Object.assign()
modifies the target object by copying properties from source objects. It directly mutates the target object.Object.create()
does not mutate any existing object. It creates a new object with the specified prototype.
//Object.assign()
const target = { a: 1, b: 2 };
const source = { b: 3, c: 4 };
const result = Object.assign(target, source);
console.log(result); // Output: { a: 1, b: 3, c: 4 }
console.log(target); // Output: { a: 1, b: 3, c: 4 }
//Object.create()
const protoObj = { a: 1, b: 2 };
const newObj = Object.create(protoObj);
console.log(newObj); // Output: { a: 1, b: 2 }
console.log(newObj.a); // Output: 1 (inherited from protoObj)
7. What is a Promise ?
A Promise in JavaScript is a returned object representing the eventual completion or failure of an asynchronous operation. It allows you to handle asynchronous operations more easily and avoid the complexities of nested callbacks, often referred to as “callback hell”. It is an assurance of returning a single value in future.
Promise has 4 states:
While a Promise object is “pending” (working), the result is undefined.
When a Promise object is “fulfilled”, the result is a value.
When a Promise object is “settled”, the result is ……………
When a Promise object is “rejected”, the result is an error object.
8. How many ways you can create an object?
- Object literal: { }
- using new operator
- constructor function
- Object.create() — using a specified prototype
- ES6 class
reference link: https://www.linkedin.com/pulse/5-ways-create-object-javascript-jayanth-babu-somineni-royjc/
9. What is meant by CSP, XSS (where do we set these CSP headers? In Client or Server)
Content Security Policy (CSP) in a web application involves configuring the server to send CSP headers in its HTTP responses.
A simple example of CSP policy that allows resources to be loaded only from the same origin:
Content-Security-Policy: default-src 'self';
This policy instructs the browser to only load resources (such as scripts, stylesheets, images, etc.) from the same origin as the web page.
By implementing CSP, you can enhance the security of your web application by reducing the risk of cross-site scripting (XSS) attacks and other types of content injection vulnerabilities.
10. What is meant by CORS? (Where do we set them)
CORS — Cross origin resource sharing
CORS is a security feature implemented by web browsers to control how web pages from one domain can request and interact with resources from another domain, enhancing security by preventing certain types of attacks.
CORS helps prevent cross-origin attacks such as CSRF (Cross-Site Request Forgery) and XSS(Cross site scripting)
How does server handle CORS for requests that involve credentials:
For server: Access-Control-Allow-Credentials header
Client side: withCredentials property set to true
How can a server handle CORS for dynamic or changing origins
Using Access-Control-Allow-Origin header
11. DDD?
12. Explain the various ways of Performance Optimization that you can do at any level (ex: CSS, JS, HTML)
references:
https://levelup.gitconnected.com/web-page-performance-core-web-vitals-lighthouse-a5287b84f240
13. What is hoisting?
hoisting behavior differs in case of variables (var, let and const ) and also function (regular function and function expression)
reference:
14. Discuss about the SOLID Principles.
Here are the five SOLID principles:
- Single Responsibility Principle (SRP) —
- Open/Closed Principle (OCP) —
- Liskov Substitution Principle (LSP) —
- Interface Segregation Principle (ISP) —
- Dependency Inversion Principle (DIP) —