Top JavaScript interview questions
******************************In progress
- JavaScript is a scripting language used to create dynamic and interactive websites. It is supported by all major web browsers.
- JavaScript is basically a client-side scripting language but it can also be used on the server-side with the help of technologies such as Node.js.
Primitive | Non-primitive |
---|---|
Boolean, NULL, undefined, BigInt, String, Number, Symbol | Object, Array |
a) Object Literals: A comma-separated set of name and value pairs that is wrapped inside curly braces.
var person = {
name: 'Surbhi',
age: 25,
occupation: 'Software Engineer'
}
b) Object.create method: TCreates a new object, by using an existing object as the prototype of the newly created object.
const person = {
name: 'Surbhi',
age: 25,
occupation: 'Software Engineer'
}
var info = Object.create(person);
console.log(info.name); // output - Surbhi
Here "person" is an existing object which is passed as a prototype to the newly created object "info"
const person = new Person();
class Person {
constructor(name) {
this.name = name;
}
}
let person = new Person('Surbhi');
console.log(person.name); //output - Surbhi
- == : While comparing two operands, checks for only value
console.log(1=="1"); // output=>>>>>>>>> true
- === : While comparing two operands, checks for value as well as data type
console.log(1==="1"); // output=>>>>>>>>> false
- JavaScript is Single-threaded
Arrow functions were introduced in ES6 (ECMAScript 2015) and provide a simpler and compact way to write functions. They are also called “fat arrow functions”
const functionName = (something) => {
return something;
}
- They use a concise syntax which makes them shorter and easier to read as compared to traditional function expressions
- They do not bind their own this value, but instead inherit the this value from the enclosing lexical scope (i.e., the scope in which it is defined)
- They do not have "prototype" property and hence cannot be used as a constructor
- If the arrow function body consists of a single expression, that expression will be implicitly returned, without the need for a return statement.
- If an arrow function has only one parameter, the parentheses around the parameter list can be omitted.
Synthetic events are objects that act as a cross-browser wrapper around a browser's native event. It has the same interface as the browser's native event, including stopPropagation() and preventDefault(), except the events work identically across all browsers.
Array destructuring is a unique feature in JavaScript that allows you to extract array's value into new variables. For e.g.,
const arr = [1,2,3];
const [num1, num2, num3] = arr;
console.log(num1); // output =====> 1
console.log(num2); // output =====> 2
console.log(num3); // output =====> 3
- Yes, using Spread Operators
const arr1 = [1,2,3,4];
const arr2 = [5,6];
const arr3 = [...arr1, ...arr2]
console.log(arr3) // output =====> [1,2,3,4,5,6]
JavaScript is a dynamically typed language, because the type of a variable is determined at runtime based on the value it holds. For e.g.,
var variable_one = "surbhi" // "string" datatype is determined at runtime
var variable_two = 20 // "number" datatype is determined at runtime
Undeclared - A variable that has not been declared or doesn't exists in the code
console.log(a); // output =====> ReferenceError: a is not defined
Undefined - A variable that has been declared but not assigned a value yet
let a;
console.log(a); // output =====> undefined
Null - Null means an empty value or a blank value. It is used to represent an intentional absence of value.
let demo = null;
console.log(demo); // output =====> null
Undefined - Undefined means the variable has been declared, but its value has not been assigned yet.
let demo;
console.log(demo); // output =====> undefined
A "let" or "const" variable is said to be in a "temporal dead zone" (TDZ) from the start of the block until code execution reaches the line where the variable is declared and initialized.
In JavaScript, variables declared with let or const are not hoisted to the top of the block scope. If you try to access a variable before it is declared, a ReferenceError will be thrown.
{
// TDZ for name variable starts here
console.log(name); // ReferenceError
let name = "surbhi"; // End of TDZ for name
}
IIFE stands for Immediately Invoked Function Expression. It is a JavaScript function that is executed as soon as it is defined.
An IIFE is typically written as an anonymous function expression that is enclosed within a set of parentheses, followed by another set of parentheses that call the function. For e.g.,
(function() {
// code goes here
})();
Hoisting is a default behavior in JavaScript where variable and function declarations are moved to the top of the current scope
Variable hoisting
console.log(a); // output =====> undefined
var a = 10;
The output of above code will be undefined because the declaration of "a" is hoisted to the top of the scope, but the initialization happens later in the code.
a=10;
console.log(a); // output =====> 10
var a;
The output of above code will be 10 because the variable "a" is hoisted to the top of the scope and its value is assigned before console.log
Function hoisting
demo(); // demo console
function demo() {
console.log('demo console');
}
The output of above code will be "demo console" because the function declaration is hoisted to the top of the scope, allowing it to be called before it is declared in the code.
**Note**
+ Only function declarations are hoisted, not the function expressions.
+ Only the declaration is hoisted, not the initialization.
In javascript, a cookie is a piece of data, stored in small text files, on the user's computer by the browser. Cookies are set, read and deleted using the document.cookie property
//**Set a cookie**
document.cookie = "username=surbhi";
//**Read a cookie**
let cookie_variable = document.cookie;
//**Delete a cookie** (set the expiration date to a past date/time)
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
Memoization is a technique used in JavaScript to optimize the performance of functions by caching the results of expensive function calls, based on their input parameters. For e.g., If a function is called multiple times with the same input parameters, then it will perform the same calculations each time. By memoizing the function, we can use the cached result.
function memoizedAdd(num1, num2) {
let cache = {};
return function (a, b) {
const key = num1 + ' and ' + num2;
if (key in cache) {
console.log('Retrieving from cache:', key);
return cache[key];
} else {
console.log('Calculating result:', key);
const result = num1 + num2;
cache[key] = result;
return result;
}
};
}
const add = memoizedAdd();
console.log(add(2, 3)); // "Calculating result:", "2 and 3", output ========> 5
console.log(add(2, 3)); // "Retrieving from cache:", "2 and 3" output ========> 5
In javascript, there are 3 ways to declare a variable - var, let, and const. However, they have some differences in their behavior and scope.
var | let | const |
---|---|---|
Function scoped | Block scoped | Block scoped |
Can be re-declared in the same scope | Can not be re-declared in the same scope | Can not be re-declared in the same scope |
Can be updated in the same scope | Can be updated in the same scope | Can not be updated in the same scope |
Hoisted to the top of their scope | Hoisted to the top but are not initialized | Hoisted to the top but are not initialized |
Can be declared without being initialized | Can be declared without being initialized | Can not be declared without being initialized |
A callback function is a function that is passed as an argument to another function. The function that receives the callback as an argument can then invoke the callback at any time during its execution.
function message(callback) {
console.log('Hi, i am message function');
callback();
}
// callback function
function callBackFun() {
console.log('Hey, I am a callback function');
}
// passing callback function as an argument to message function
message(callBackFun);
Yes, we can have both with the same name. But when we do this, the local variable will take precedence over the global variable within the scope of the function or block of code in which it is declared.
However, outside of that scope, the global variable will still be accessible using its name.
let a = 10;
function Demo(){
let a = 20;
console.log(a, "local scope");
}
Demo();
console.log(a, "global scope");
Local storage and session storage are web storage provided by web browsers to store data on the client-side
Local Storage - Data stored in local storage will persist even after the browser window is closed or the user navigates away from the website and it is available across all windows and tabs of the same origin.
Session Storage - Data stored in session storage will be deleted when the browser window is closed or the session ends and it is available only within the same window or tab that created the data.
map() and forEach() are array methods that can be used to iterate over an array. map()
- map() method receives a function as an argument, executes it once for each array element and returns a new array
- It is generally used when we need to modify/change data, because it returns a new array with the transformed data
- It is chainable because we can attach sort(), filter() etc. after performing a map() method on an array
const arr = [1,2,3,4,5]
let result = arr.map(x => x * x)
console.log(result) // output ========> [1,4,9,16,25]
forEach()
- forEach() method receives a function as an argument, executes it once for each array element but returns undefined.
- It is generally used when we just need to iterate over an array
- It is not chainable
const arr = [1,2,3,4,5]
let result = arr.forEach(x => x * x)
console.log(result) // output ========> undefined
- The rest operator was introduced in ES6 (ECMAScript 2015) and it is represented by three dots (...)
- It is used in function parameters and allows you to represent an indefinite number of arguments as an array
function addition(...numbers) {
return numbers.reduce((a,b)=>a+b);
}
console.log(addition(1, 2, 3, 4)); // output ========> 10
- It collects all the remaining arguments passed to a function into an array
function profile(name, designation,...location) {
return location
}
console.log(profile("surbhi","SE","India","Indore","M.P")); // output ========> ["India", "Indore", "M.P"]
- The spread operator was introduced in ES6 (ECMAScript 2015) and it is represented by three dots (...)
- It allows an iterable to be spread into individual elements
const arr = [1, 2, 3, 4,5];
console.log(...arr); // output ======> 1, 2, 3, 4, 5
- It can be used to copy the elements of an existing array into a new array, or to concatenate arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [...arr1, ...arr2];
console.log(arr3); // output =======> [1, 2, 3, 4, 5, 6]
- It can be used to copy the properties of an existing object into a new object
const obj1 = { a:1, b:2 };
const obj2 = { c:3 };
const obj3 = { ...obj1, ...obj2 };
console.log(obj3); // output ========> { a: 1, b: 2, c: 3 }
async and defer are the attributes used with the script tag in HTML to load javaScript files.
Async - The script is loaded in parallel to the HTML parsing, and executed as soon as it is available i.e., it executes the script immediately after it is loaded. It can be useful for scripts that don't depend on the DOM.
Defer - The script is loaded in parallel to the HTML parsing, and executed after the page is completely loaded i.e., it waits until the page has finished parsing. It can be useful for scripts that depend on the DOM.
- The nullish coalescing (??) operator is a logical operator
- It allows you to check if a value is either null or undefined
- It returns its right-hand side operand if its left-hand side operand is null or undefined, otherwise returns its left-hand side operand
console.log((null || undefined) ?? "foo"); // output ========> "foo"
console.log("hello" ?? "foo"); // output ========> "hello"
Parameter - A parameter is a variable that is defined during a function declaration or definition. It represents a value that the function or method expects to receive as an input.
Argument - An argument is the actual value that is passed to a function or method when it is called.
function Demo(parameter1, parameter2){
something------
something------
}
Demo(argument1, argument2);
A closure is a combination of a function and the environment in which it was created(lexical scope). It gives you access to an outer function's scope from an inner function even if the outer function has returned
function Demo() {
let name = "Surbhi";
function displayName() {
console.log(name);
}
return displayName;
}
const result = Demo();
result();
Function Declaration
- A function declaration defines a function using the function keyword, followed by the function name
- We can call a function, declared using a function declaration, before it is defined. Because it is hoisted to the top of its scope
- It does not require a variable assignment
function Message() {
console.log("Welcome Message"); // output ========> Welcome Message
}
Message();
Function Expression
- A function Expression is similar to a function declaration without the function name
- We can not call a function, declared using a function expression, before it is defined
- It can be stored in a variable assignment
const Message = function() {
console.log("Welcome Message"); // output ========> Welcome Message
}
Message();
- Using the array literal notation
const arr = [1,2,3,4,5];
- Using the Array() constructor
const arr = new Array(1, 2, 3, 4, 5);
window object - window is the topmost object. It represents the browser window or tab containing a DOM document. It provides various properties and methods to manipulate the browser window, such as window.alert(), window.confirm(), and window.location.
document object - document represents the HTML document that is being displayed in the window. It provides properties and methods to manipulate the HTML elements in the document, such as document.title, document.getElementById(), and document.createElement().
- Strict mode was introduced in ECMAScript 5
- It performs additional checks on your code to prevent certain types of bugs and errors that may go unnoticed e.g., using undeclared variables, using duplicate property names in objects
- It can be enabled at either the global level or at the function level
- It can't be apply to block statements enclosed in {} braces
- To invoke strict mode, put the exact statement “use strict”; or ‘use strict’;
Using length property
let arr = [1, 2, 3, 4, 5];
arr.length = 0;
console.log(arr); // output ========> []
Assigning it to a new empty array
let arr = [1,2,3,4,5];
arr = [];
console.log(arr); // output ========> []
Using the splice() method
let arr = [1, 2, 3, 4, 5];
arr.splice(0, arr.length);
console.log(arr); // output ========> []
- In Javascript, NaN stands for "Not a Number"
- It is a global property that represents an unrepresentable mathematical result
- It is returned when a mathematical operation has no meaningful result. E.g., dividing zero by zero, multiplying/dividing a non-numeric value by a number etc.
console.log(0/0); // output ========> NaN
console.log("a"*1); // output ========> NaN
console.log("a"/1) // output ========> NaN
console.log(Math.sqrt(-1)); // output ========> NaN
console.log(parseInt("blabla")); // output ========> NaN
- Use camelCase (lowercase for the first word, then uppercase for subsequent words) for variable and function names
- Use PascalCase for class names (uppercase for the first letter of each word)
- Use "is" or "has" as prefixes for boolean variables
- Use UPPERCASE for constants
- Use descriptive and meaningful names for your variables, functions, and classes.
//variable
let firstName = "Surbhi";
//function
function displayName() {
return "Surbhi Dighe";
}
displayName();
//boolean
let isLoading = false;
let hasName = true;
//constants
let SECONDS = 60;
//class
class DisplayName {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
var name = new DisplayName('Surbhi', 'Dighe');
call(), apply(), and bind() methods are used to attach a function into an object and call the function as if it belonged to that object.
call() - call() is used to invoke a function immediately with a specified this value and allows you to pass the arguments one by one
let person = {name: 'Surbhi'};
function printName(message) {
console.log(message + ' ' + this.name); // output ========> "Hello Surbhi"
}
printName.call(person, 'Hello');
apply() - apply() is used to invoke a function immediately with a specified this value and allows you to pass the arguments as an array
let person = {name: 'Surbhi'};
function printName(message) {
console.log(message + ' ' + this.name); // output ========> "Hello Surbhi"
}
printName.apply(person, ['Hello']);
bind() - bind() returns a new function (which can be invoked anytime), with a specified this value and allows you to pass in arguments
let person = {name: 'Surbhi'};
function printName(message) {
console.log(message + ' ' + this.name); // output ========> "Hello Surbhi"
}
let sayHello = printName.bind(person, "Hello");
sayHello();
isNaN() is a built-in JavaScript function. It takes a single argument and returns true if the argument is not a number, otherwise it returns false.
let num1 = 5;
let num2 = "hi";
console.log(isNaN(num1)); // output ========> false
console.log(isNaN(num2)); // output ========> true
The value of 'this' is determined by the context in which it is used. In general, 'this' keyword refers to the object it belongs to. The 'this' keyword in JavaScript can have different values depending on where it is used -
- If it is used inside a method, then it refers to the object that it belongs to
- If it is used inside any function or alone (i.e outside any function or method), then it referes to the global object
- If it is used in the context of an event handler, such as a click event, then it refers to the element that triggered the event
Single-line comments - Add comments using 2 forward slashes //
// this is a single line comment
Multi-line comments - Enclose the text between /* and */
/*
This is a
multiline comment
example
*/
The typeof operator returns a string that indicates the data type of the variable/value.
let var1 = "Surbhi";
let var2 = 10;
console.log(typeof var1); // output ========> "string"
console.log(typeof var2); // output ========> "number"
console.log(typeof "hello"); // output ========> "string"
console.log(typeof 2); // output ========> "number"
console.log(typeof true); // output ========> "boolean"
Yes, JavaScript is a case-sensitive language. For e.g., the variables firstName and firstname are considered to be two different variables.
let firstName = "Surbhi";
console.log(firstname); // output ========> Uncaught ReferenceError: firstname is not defined
Both are used to add elements to an array, but they add elements in different ways.
push() - It adds one or more elements to the end of an array and returns the new length of the array.
let arr = [1,2,3,4];
let newArr = arr.push(5,6,7);
console.log(newArr); // output ========> 7
console.log(arr); // output ========> [1, 2, 3, 4, 5, 6, 7]
unshift() - It adds one or more elements to the beginning of an array and returns the new length of the array.
let arr = [1,2,3,4];
let newArr = arr.unshift(5,6,7);
console.log(newArr); // output ========> 7
console.log(arr); // output ========> [5, 6, 7, 1, 2, 3, 4]
Both are used to remove elements from an array, but they remove elements in different ways.
pop() - It removes the last element of an array and returns the removed element.
let arr = [1,2,3,4];
let newArr = arr.pop();
console.log(newArr); // output ========> 4
console.log(arr); // output ========> [1,2,3]
shift() - It removes the first element of an array and returns the removed element.
let arr = [1,2,3,4];
let newArr = arr.shift();
console.log(newArr); // output ========> 1
console.log(arr); // output ========> [2,3,4]
******************************In progress