React Software Engineer Questions — Part 1

Chanuga Tharindu
8 min readOct 20, 2023

--

Photo by Árpád Czapp on Unsplash

In this article I will be talking about some of the interview questions that could be asked from you in a React Software Engineering interview. This will be the part 1 of the series.

In this article I will be talking more about Questions that could be asked related to JavaScript.

  1. What is hoisting in JavaScript ?

Hoisting is a fundamental concept in JavaScript that affects the way variables and function declarations are processed by the JavaScript engine during the compilation and execution phases.

Variable Declarations : When JavaScript code is executed, variable declarations are moved to the top of their containing function or scope. This means that you can use a variable before it’s declared, and it won’t result in an error, although the variable will be undefined if you try to access its value before assigning one.

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

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

This behavior applies to variables declared with var, but not to those declared with let or const, which are block-scoped and are not initialized until the actual declaration.

Function Declarations : Function declarations are also hoisted to the top of their containing scope. This means you can call a function before it’s declared in your code.

sayHello(); // “Hello”

function sayHello() {
console.log(“Hello”);
}

Just like with variable declarations, the function declaration is effectively moved to the top like this.

function sayHello() {
console.log(“Hello”);
}

sayHello(); // “Hello”

Variable Assignment : Only variable declarations are hoisted, not their assignments. So, if you have a variable assignment before the declaration, you’ll still get a reference error.

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

To write clean and maintainable code, it’s a good practice to declare your variables and functions at the top of their containing scope to avoid any confusion that might arise from hoisting. Additionally, using let and const instead of var for variable declarations can help prevent certain issues related to hoisting since they have block scope and don't get hoisted to the entire function or scope.

2. What is the difference between letand var ?

Scope :

  • var: Variables declared with var are function-scoped. This means they are only accessible within the function in which they are declared. If declared outside of any function, they are globally scoped.
  • let: Variables declared with let are block-scoped. They are accessible only within the block (enclosed by curly braces) in which they are declared, whether it's a function, a loop, or any other block.

Hoisting :

  • var: Variables declared with var are hoisted to the top of their containing function or global scope. This means that you can use a var variable before it's declared, but it will be undefined until the actual declaration is reached.
  • let: Variables declared with let are also hoisted, but they are not initialized (they do not have a value of undefined) until the actual declaration is reached. So, referencing a let variable before its declaration results in a ReferenceError.

Re-declaration :

  • var: You can re-declare a variable using var within the same scope without any error. This can sometimes lead to unintended consequences and make debugging more difficult.
  • let: Variables declared with let cannot be re-declared within the same scope. Attempting to re-declare a let variable will result in a syntax error.

3. What is event loop in JavaScript ?

The event loop is a fundamental concept in JavaScript that plays a crucial role in managing asynchronous code execution. It is the mechanism that allows JavaScript to handle events, callbacks, and non-blocking operations efficiently.

Here’s how the event loop works,

Call Stack : JavaScript code is executed in a single-threaded environment. When a script is run, it starts by executing the code line by line in the order it appears. This execution is managed by the call stack, which is a data structure that keeps track of the currently executing function and its context.

Asynchronous Operations : JavaScript is often used for operations that are non-blocking, such as fetching data from a server, reading files, or handling user interactions. When these asynchronous operations are encountered, JavaScript does not wait for them to complete. Instead, it offloads them to the browser or the environment’s APIs, which run in the background.

Callback Queue : Once an asynchronous operation is completed, a callback function is pushed into the callback queue. Callbacks are functions that are scheduled to run once the call stack is empty.

Event Loop : The event loop continuously monitors the call stack and the callback queue. It checks if the call stack is empty, and if so, it takes the first function from the callback queue and pushes it onto the call stack for execution.

Here’s a simplified example of how the event loop works

console.log(“Start”);

setTimeout(function () {
console.log(“Timeout callback”);
}, 1000);

console.log(“End”);

// Output:
// “Start”
// “End”
// (After about 1 second)
// “Timeout callback”

In this example, “Start” and “End” are logged to the console before the setTimeout callback. The setTimeout function schedules the callback to be executed after approximately 1 second. The event loop waits for the call stack to be empty, then pushes the callback onto the stack for execution.

The event loop is essential for managing asynchronous operations in JavaScript, and it’s what allows JavaScript to remain responsive and handle multiple tasks without blocking the main thread. Understanding how the event loop works is crucial for writing efficient and responsive JavaScript code, especially in web development where handling user interactions and network requests is common.

4. What is setTimeout and setInterval ?

setTimeout

  • setTimeout is used to execute a function or a code block after a specified time delay (in milliseconds).
  • It takes two arguments: the function to execute and the delay in milliseconds.
  • It schedules a one-time execution of the provided function after the specified delay.

setTimeout(function() {
console.log(“This code runs after a delay of 2000 milliseconds (2 seconds).”);
}, 2000);

  • You can also pass additional arguments to the function

setTimeout(function(name) {
console.log(`Hello, ${name}!`);
}, 1000, “John”);

setInterval

  • setInterval is used to repeatedly execute a function or a code block at a specified time interval (in milliseconds).
  • It takes two arguments: the function to execute and the interval in milliseconds.
  • It schedules the function to run at the specified interval, and it continues to do so until you explicitly cancel it.

var count = 0;
var intervalId = setInterval(function() {
console.log(`This code runs every 1000 milliseconds (1 second). Count: ${count}`);
count++;
if (count >= 5) {
clearInterval(intervalId); // Cancel the interval after running 5 times.
}
}, 1000);

In the example above, setInterval is used to run the provided function every 1 second for a total of 5 times.

Both setTimeout and setInterval are commonly used in scenarios like creating animations, polling for data updates, scheduling periodic tasks, and handling various time-based actions. However, you should be cautious when using setInterval for long-running tasks, as it can lead to overlapping executions if the previous execution takes longer than the specified interval. To avoid this, you can use setTimeout recursively within the function to create a delay between executions.

5. What are the new features introduced in ES6 ?

  1. Block-Scoped Variables with let and const:
  • let and const allow you to declare variables that are block-scoped, meaning they are limited to the block or statement in which they are declared. This addresses the issues with var and hoisting.

2. Arrow Functions:

  • Arrow functions provide a more concise syntax for defining functions, with implicit return and lexical this binding.

3. Template Literals:

  • Template literals allow for string interpolation and multi-line strings using backticks (`) instead of single or double quotes.

4. Default Parameters:

  • You can specify default values for function parameters, reducing the need for explicit checks for undefined.

5. Rest and Spread Operators:

  • The rest operator (...) allows you to gather the remaining parameters into an array, while the spread operator can expand an array or object into individual elements or properties.

6. Destructuring Assignment:

  • Destructuring enables you to extract values from arrays and objects using a concise syntax.

7. Classes:

  • ES6 introduced a class syntax for defining constructor functions and prototypes, making it more similar to class-based inheritance in other programming languages.

8. Modules:

  • ES6 introduced a module system with import and export statements for organizing and managing code in separate files.

9. Promises:

  • Promises provide a more structured way to handle asynchronous operations, making it easier to manage and chain asynchronous tasks.

10. New Array and Object Methods:

  • ES6 introduced new array methods like map, filter, reduce, and forEach, as well as new object methods like Object.keys, Object.values, and Object.entries.

11. Symbol Data Type:

  • Symbols are a new primitive data type that can be used as unique property keys, helping to avoid naming collisions.

12. Generators:

  • Generators allow you to create iterable objects with a special syntax using the function* keyword.

13. Map and Set Data Structures:

  • ES6 introduced two new built-in data structures, Map and Set, for more efficient data storage and retrieval.

14. Enhanced Object Literals:

  • Object literals can now have shorthand property names, computed property names, and method definitions.

15. String Methods:

  • ES6 added new string methods like startsWith, endsWith, includes, and repeat.

16. Binary and Octal Literals:

  • You can now use binary (0b) and octal (0o) literals in addition to hexadecimal (0x) literals.

17. New Syntax for Iterating Over Data:

  • ES6 introduced the for...of loop for easily iterating over values in arrays, strings, maps, sets, and other iterable objects.

18. New Error Object Properties:

  • Error objects now have standardized properties like name and stack.

These are some of the key features introduced in ES6, which significantly improved the readability, maintainability, and functionality of JavaScript code. ES6 marked a major advancement in the language, and its features have become a standard part of modern JavaScript development.

6. What is deep copy and shallow copy ?

Deep copy and shallow copy are two different techniques used to duplicate or clone objects and data structures in programming. The main difference between them lies in how they handle nested objects and their references.

Shallow Copy

  • A shallow copy creates a new object, but it does not create copies of the nested objects within the original object. Instead, it copies references to those nested objects.
  • If you modify a nested object in the copied structure, the change will also affect the original object because both the original and the copied structure point to the same nested object.
  • Shallow copying is a simpler and faster process, especially for large data structures.
  • In JavaScript, you can use methods like Object.assign(), the spread operator (...), or the slice() method (for arrays) to create shallow copies.

const original = {
name: “John”,
address: { city: “New York” },
};

const shallowCopy = { …original };

shallowCopy.name = “Alice”;
shallowCopy.address.city = “Los Angeles”;

console.log(original.name); // “John” (not modified)
console.log(original.address.city); // “Los Angeles” (modified)

Deep Copy:

  • A deep copy creates a completely independent copy of the original object, including all nested objects and their properties. Changes to the copied structure do not affect the original object.
  • Deep copying is more memory-intensive and time-consuming, especially for complex nested structures or large datasets.
  • There isn’t a built-in method in JavaScript for deep copying objects, so you often need to use custom functions or external libraries like Lodash’s _.cloneDeep().

const original = {
name: “John”,
address: { city: “New York” },
};

const deepCopy = _.cloneDeep(original);

deepCopy.name = “Alice”;
deepCopy.address.city = “Los Angeles”;

console.log(original.name); // “John” (not modified)
console.log(original.address.city); // “New York” (not modified)

Thanks for reading.

In the next one I will discuss about CSS, React and Redux related questions.

--

--