DEV Community

Cover image for Interview Questions for Web Developer - JavaScript
Mykhailo Toporkov 🇺🇦
Mykhailo Toporkov 🇺🇦

Posted on • Updated on

Interview Questions for Web Developer - JavaScript

Navigation


JavaScript Basics

1. What is the javascript? - Answer

2. What is the Scope? - Answer

3. What is an Event Loop? How does it work? - Answer


Variables & Data types

1. What declaring variables does JavaScript have? What is the difference between them?

  • var: var was the original way to declare variables in JavaScript before ES6. Variables declared with var have function scope or global scope if declared outside a function. They can be redeclared and updated.

  • let: Introduced in ES6, let allows block-scoped variables. Variables declared with let are limited to the block (enclosed by curly braces) in which they are defined. They cannot be redeclared in the same scope but can be updated.

  • const: Also introduced in ES6, const is used to declare constants whose values cannot be re-assigned or re-declared. const variables are block-scoped and must be initialized at the time of declaration.

2. What are the various data types that exist in JavaScript? -
There are eight data types that are present in JavaScript:

  • String
  • Number
  • Boolean
  • Object
  • Null
  • Undefined
  • BigInt
  • Symbol

3. What is the difference between null and undefined ?
The undefined usually occurs as a default value in JavaScript, representing the absence of an assigned value, while null is explicitly set by the programmer to indicate a deliberate absence of a value. Both null and undefined are distinct types in JavaScript, but they are often used interchangeably to signify absence or lack of a meaningful value.

4. How to check the type of some operand? What types have the following operands: null, undefined, [] and NaN?

For type checking a type, use typeof operator that returns a string indicating the type of the operand's value.

console.log(typeof null) // object
console.log(typeof undefined) // undefined
console.log(typeof NaN) // number
console.log(typeof []) // object
Enter fullscreen mode Exit fullscreen mode

5. What limitations have numbers in JavaScript and how to overcome them?

JavaScript as most programming languages has problems with math and huge/small numbers, which all come from the hardware itself. As a result, we get some strange behavior in our codebase e.g.

console.log(0.1 + 0.2); // Output: 0.30000000000000004 (rounded due to precision)
Enter fullscreen mode Exit fullscreen mode
console.log(9007199254740992); // Output: 9007199254740992 (accurate)
console.log(9007199254740993); // Output: 9007199254740992 (loss of precision)
Enter fullscreen mode Exit fullscreen mode

Precision and Representation:

  • JavaScript numbers are stored as 64-bit floating-point numbers, limiting their range. Numbers outside the range of ±(2^53 - 1) may not be represented accurately.

  • JavaScript uses the IEEE 754 standard for representing numbers, which can lead to precision issues with floating-point arithmetic. This can cause unexpected behavior when performing calculations involving decimals due to limited precision.

In practice when we work with huge/small and decimal numbers, we are required to mind Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER edges. if the number exceeds them use BigInt instead of regular numbers. For decimals, we can be used in-build Math functions to get the required results.

const bigIntNum = 123456789012345678901234567890n; // Using the "n" suffix
const anotherBigInt = BigInt("9007199254740993"); // Creating from a string using BigInt()

/// 

const result = 0.1 + 0.2;
const fixedResult = (result).toFixed(1); // Round to one decimal place

console.log(parseFloat(fixedResult)); // Output: 0.3
Enter fullscreen mode Exit fullscreen mode

Functions & Loops

1. Name ways of declaring functions and their differences in JavaScript?

  • Function declaration The function declaration uses the keyword function to declare a function, this method allows to use function before it is defined e.g.
doSomething()

function doSomething () {
  //...some actions
}
Enter fullscreen mode Exit fullscreen mode
  • Function Expression The assigning a function to some variable, in this case, if the function is called before the declaration causes the ReferenceError
doSomething() //output: ReferenceError

const doSomething = function () {
  console.log("Function Expression worked")
}

doSomething() // output: "Function Expression worked"
Enter fullscreen mode Exit fullscreen mode

2. What are arrow functions, How are they different from regular functions and where should use them?
The arrow functions are a concise way to write functions in JavaScript introduced in ES6 (ECMAScript 2015) with a more compact syntax compared to regular functions. They differ from regular functions in a few ways:

  • use => to define a function;
  • do not have its own this context; they inherit this from the surrounding code;
  • do not have the arguments object;

Can be used as callbacks inside promises, as short anonymous functions inside array methods, where you want to preserve the lexical scope of this

Examples:

//With many arguments:
const doSomething = (a, b) => {return a + b};

//With instant return:
const doSomething = (a, b) => a + b;

//With one argument:
const doSomething = a => a + 1;

//Inside array:
const sum = [1, 2, 3].reduce((acc, cur) => acc + cur, 0);

//Inside promise
fetch('https://some-api').then(res => res.json());
Enter fullscreen mode Exit fullscreen mode

3. What IIFE stands for and where should be used?
IIFE stands for "Immediately Invoked Function Expression."

An IIFE is a JavaScript design pattern that involves defining and immediately executing a function. It is constructed by enclosing the function within parentheses ( ) to create a function expression and then adding an additional set of parentheses ( ) immediately after to invoke the function e.g.

(function() {
    // Function body
})();

(() => {
   // Function body
})()
Enter fullscreen mode Exit fullscreen mode

Use cases for IIFE:

  • Encapsulation: IIFEs are commonly used to create a new scope, preventing variable declarations from polluting the global scope. This helps avoid naming conflicts and keeps variables private.

  • Initialization: They are useful for initializing code that should run once when the script loads, setting up configurations, or executing setup tasks.

  • Module Patterns: IIFEs are a building block for various module patterns in JavaScript, like the revealing module pattern or module encapsulation, allowing the creation of private variables and functions while exposing only necessary functionalities.

4. What is closure in JavaScript and how it works?
In JavaScript, a closure is a combination of a function and the lexical environment within which that function was declared. Closures allow functions to access and utilize variables from their outer scope even after the outer scope has finished executing.

Here's how closures work:

  1. Lexical Scoping: JavaScript uses lexical scoping, which means that functions can access variables defined in their outer scope at the time they were created, regardless of where they are called from.

  2. Function within a Function: When a function is defined inside another function, the inner function has access to the outer function's variables and parameters, forming a closure.

  3. Preservation of the Outer Scope: Closures "remember" the variables from their outer scope even after the outer function has finished executing. This allows the inner function to maintain access to those variables.

const mainFunction = () => {
  const arr = [];

  return (value) => {
   arr.push(value);
   console.log(arr)
 }
}

const returnedFunction = mainFunction();

returnedFunction("1") // will console ["1"];
returnedFunction("2") // will console ["1", "2"]
Enter fullscreen mode Exit fullscreen mode

5. What is the anonymous function?
An anonymous function in JavaScript is a function that does not have a name assigned to it. Instead of being declared with a specific identifier (name), it is created inline without a name reference. These functions are often used as callbacks or function expressions where the function itself doesn't need to be named or referenced elsewhere in the code.

const myFunction = function() {
  console.log('This is an anonymous function');
};

// Using an anonymous function as a callback
setTimeout(function() {
  console.log('This function will execute after 1 second');
}, 1000);
Enter fullscreen mode Exit fullscreen mode

Objects & Arrays

1. Is the one {} equal another {}? How to compare two objects?

In JavaScript, when comparing two objects using the equality operators (== or ===), these operators check for equality by comparing the references to the objects, not their contents.

const objA = { a: 1, b: 2, c: 3 };
const objB = { a: 1, b: 2, c: 3 };

console.log(objA === objB); // false
Enter fullscreen mode Exit fullscreen mode

Actually, there are several ways to compare objects in JavaScript. The first that may come to mind is to iterate through keys and values and compare them that will look something like:

function isEqual(obj1, obj2) {
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);

  if (keys1.length !== keys2.length) {
    return false;
  }

  for (const key of keys1) {
    if (obj1[key] !== obj2[key]) {
      return false;
    }
  }

  return true;
}

const objA = { a: 1, b: 2, c: 3 };
const objB = { a: 1, b: 2, c: 3 };
console.log(isEqual(objA, objB)); // true
Enter fullscreen mode Exit fullscreen mode

Also we can transform objects to JSON strings and compare them like:


const objA = { a: 1, b: 2, c: 3 };
const objB = { a: 1, b: 2, c: 3 };

const stringA = JSON.stringify(objA);
const stringB = JSON.stringify(objB);

console.log(stringA === stringB); // true
Enter fullscreen mode Exit fullscreen mode

Or to use some third-party libs like isEqual from lodash.

2. How to copy an Object in JavaScript?
There are a several ways to copy an Object in JavaScript:

Object.assign(): Creates a shallow copy of an object. Copies enumerable own properties from one or more source objects to a target object. Modifies the target object and returns it. Non-enumerable properties and properties on the prototype chain are not copied.

const originalObject = { a: 1, b: 2 };
const copiedObject = Object.assign({}, originalObject);
Enter fullscreen mode Exit fullscreen mode

Spread syntax (...): Creates a shallow copy of an object. Copies enumerable own properties from the source object(s) to the new object. Can be used to merge objects or create new objects with copied properties. Similar to Object.assign(), it doesn't deeply clone nested objects or handle non-enumerable properties.

const originalObject = { a: 1, b: 2 };
const copiedObject = { ...originalObject };
Enter fullscreen mode Exit fullscreen mode

JSON.stringify() and JSON.parse(): Creates a deep copy of an object but works only with JSON-safe data. Converts the object to a JSON string and then parses it back into a new object. Loses reference to functions, non-JSON-safe objects (like Date objects), and non-enumerable properties.

const originalObject = { a: 1, b: 2 };
const copiedObject = JSON.parse(JSON.stringify(originalObject));
Enter fullscreen mode Exit fullscreen mode

Object.create(): Creates a new object with the specified prototype object and properties. Allows for setting the prototype of the new object explicitly. Can copy properties from another object, but doesn't create a direct copy of the source object's properties.

const originalObject = { a: 1, b: 2 };
const copiedObject = Object.create(Object.getPrototypeOf(originalObject), Object.getOwnPropertyDescriptors(originalObject));
Enter fullscreen mode Exit fullscreen mode

3. How to check that an object has property?
Using the in operator, however, it also returns true if the object's prototype has this property. The second approach uses hasOwnProperty() method on an object.

const proto_obj = {
    name: 'user'
};

const obj = {
  color: 'red'
}

obj.__proto__ = proto_obj;

console.log('color' in obj); // true
console.log('name' in obj); // true
console.log(obj.hasOwnProperty("color")) // true
console.log(obj.hasOwnProperty("name")) // false
Enter fullscreen mode Exit fullscreen mode

Prototypes, inheritance and this

1. What is a prototype in JavaScript? How to work with it?
In JavaScript, everything is basically primitive or an object. Objects on the other hand have a prototype. The prototype is a reference to another object that the current object inherits properties and methods from. It forms the basis for JavaScript's prototypal inheritance.

2. How to check that an object has property?
Using the in operator, however, it also returns true if the object's prototype has this property. The second approach uses hasOwnProperty() method on an object.

const proto_obj = {
    name: 'user'
};

const obj = {
  color: 'red'
}

obj.__proto__ = proto_obj;

console.log('color' in obj); // true
console.log('name' in obj); // true
console.log(obj.hasOwnProperty("color")) // true
console.log(obj.hasOwnProperty("name")) // false
Enter fullscreen mode Exit fullscreen mode

3. Explain the this keyword, and how it works?

In JavaScript, the this keyword is a special identifier that refers to the current instance of an object or the context in which a function is invoked. The value of this is determined by how a function is called or how an object is accessed.

Here are some examples of usages this:

  • When used inside a function, this depends on how the function is called. If the function is a regular function (not a method of an object or part of a class), this refers to the global object (or undefined in strict mode).
function myFunction() {
  console.log(this);
}

myFunction(); // global object | window
Enter fullscreen mode Exit fullscreen mode
  • When used inside a method (a function that is a property of an object), this refers to the object on which the method is called.
const myObject = {
  myMethod: function() {
    console.log(this);
  }
};

myObject.myMethod(); // Points to myObject
Enter fullscreen mode Exit fullscreen mode
  • When used inside a constructor function (a function called with the new keyword to create an instance), this refers to the newly created instance.
function MyClass() {
  this.myProperty = 42;
}

const myInstance = new MyClass();
console.log(myInstance.myProperty); // 42
Enter fullscreen mode Exit fullscreen mode
  • In event handlers, this often refers to the DOM element that triggered the event.
document.getElementById('myButton').addEventListener('click', function() {
  console.log(this); // Points to the clicked button element
});
Enter fullscreen mode Exit fullscreen mode

4. What is call(), apply() and bing()?
The call(), apply(), and bind() methods are used to explicitly set the value of this for a function. They allow you to control the context in which a function is executed. These methods are often used in situations where the default behavior of this is not sufficient, such as when you want to invoke a function with a specific object as its context.

Usage examples:

const obj1 = { name: 'Object 1' };

function sayHello(greeting) {
  console.log(`${greeting}, ${this.name}`);
}

sayHello.call(obj1, 'Hello'); // Outputs: Hello, Object 1
Enter fullscreen mode Exit fullscreen mode
const obj2 = { name: 'Object 2' };

function sayHi(greeting) {
  console.log(`${greeting}, ${this.name}`);
}

sayHi.apply(obj2, ['Hi']); // Outputs: Hi, Object 2
Enter fullscreen mode Exit fullscreen mode
const obj3 = { name: 'Object 3' };

function greet(greeting) {
  console.log(`${greeting}, ${this.name}`);
}

const boundFunction = greet.bind(obj3, 'Greetings');
boundFunction(); // Outputs: Greetings, Object 3
Enter fullscreen mode Exit fullscreen mode

Other (For now)

1. What is the difference between == and ===?
In JavaScript, == (equality operator) and === (strict equality operator) are used for comparison, but they differ in how they evaluate values:

console.log(1 == '1') // true
console.log(1 === '1') // false
Enter fullscreen mode Exit fullscreen mode

2. What is the difference between LocalStorage, SessionStorage та cookies?

  • LocalStorage is a web storage API in web browsers that allows for persistent storage of key-value pairs in the browser with no expiration date, remaining stored even after the browser is closed.

  • SessionStorage is another web storage API that stores data in the browser for the duration of the page session, clearing the data when the session ends or the browser is closed.

  • Cookies are small pieces of data sent from a website and stored in the user's browser, capable of holding limited information and having expiration dates, often used for tracking, authentication, and personalization purposes.

3. What is the difference between for..of and for...in ?

  • for...of is used for iterating over values of iterable objects like arrays and strings.

  • for...in is used for iterating over keys or property names of objects, including inherited properties in the prototype chain.

4. What is Map & Set? When it should be used?

  • Map: A Map is a collection of key-value pairs where each key can be of any data type, including objects or primitive values. It maintains the insertion order of its elements, and keys can be iterated in the order of their insertion. It allows storing unique keys and offers various methods to interact with the data, such as set(), get(), delete(), has(), etc. Use Map when you need to associate keys with values, especially when the keys are not simple strings or when you want to maintain the insertion order of key-value pairs. It's useful for scenarios where a unique identifier (key) is associated with some data (value).

  • Set: A Set is a collection of unique values, where each value must be unique within the set. It does not allow duplicate elements, and it also maintains the insertion order of elements. It provides methods like add(), delete(), has(), etc., to manage and interact with the set. Use Set when you need to maintain a collection of unique values and you want to ensure that each element appears only once within the collection. It's useful for removing duplicates from arrays, managing unique values, or checking for the existence of elements efficiently without needing to manage uniqueness manually.

5. How is asynchronous code executed in JavaScript?
In JavaScript, asynchronous code is executed using an event-driven, non-blocking model. When an asynchronous operation is initiated (such as fetching data from a server or setting a timer), it gets queued in the event loop, allowing the main execution thread to continue processing other tasks. Once the asynchronous operation is completed or ready, its associated callback function or promise is placed in the callback queue. The event loop continuously checks for completed tasks in the callback queue and executes their corresponding callback functions, allowing the program to handle asynchronous tasks without blocking the main thread, ensuring responsiveness in applications.

6. What are the three phases of event propagation?
Capturing > Target > Bubbling. During the capturing phase, the event goes through the ancestor elements down to the target element. It then reaches the target element, and bubbling begins.
event_propagation


Sources / Literature

Top comments (1)

Collapse
 
robinamirbahar profile image
Robina

Very detailed article