Interview Question on JS Variable

anikakash

Anik Dash Akash

Posted on November 5, 2024

Interview Question on JS Variable

1. Basic Definitions & Differences :

Q: What are let, const, and var, and how do they differ?

  • var was the original way to declare variables in JavaScript. It has function-level scope and is prone to hoisting issues.

  • let and const were introduced in ES6 (ES2015) and have block-level scope, making them more predictable.

  • let allows you to declare a variable that can be reassigned, whereas const creates a constant reference.

var a = 10;
let b = 20;
const c = 30;

Enter fullscreen mode Exit fullscreen mode

Q: When should you use let vs const?

  • Use const by default. Only use let if you know the variable needs to be reassigned later.

  • This improves code readability and prevents accidental reassignments.

const apiUrl = 'https://api.example.com'; // Won't change
let userScore = 0; // Will change as the user scores points

Enter fullscreen mode Exit fullscreen mode

Q: Why is var generally discouraged in modern JavaScript?

  • var has function-level scope and gets hoisted, which can cause unexpected behavior and bugs. let and const are block-scoped and reduce these issues.
function example() {
   if (true) {
      var x = 10; // Accessible outside the if block
   }
   console.log(x); // 10
}

function exampleLet() {
   if (true) {
      let y = 20; // Block-scoped
   }
   console.log(y); // ReferenceError
}

Enter fullscreen mode Exit fullscreen mode

2. Scope and Hoisting :

Q: Explain the concept of scope in JavaScript (global, function, block).

  • Global Scope: Variables declared outside functions are globally accessible.

  • Function Scope: Variables declared inside a function with var are function-scoped.

  • Block Scope: Variables declared inside a block (e.g., {}) with let or const are block-scoped.

var globalVar = 'I am global';

function testScope() {
   var functionVar = 'I am function-scoped';
   if (true) {
      let blockVar = 'I am block-scoped';
      console.log(blockVar); // Works fine
   }
   console.log(blockVar); // ReferenceError
}

Enter fullscreen mode Exit fullscreen mode

Q: How does scope differ between var, let, and const?

  • var has function scope; let and const have block scope.

Q: What is hoisting, and how does it affect var, let, and const?

  • Hoisting is JavaScript's behavior of "moving" variable and function declarations to the top of their scope. Only var is hoisted and initialized with undefined. let and const are hoisted but not initialized, leading to the Temporal Dead Zone (TDZ).
console.log(a); // undefined due to hoisting
var a = 10;

console.log(b); // ReferenceError due to TDZ
let b = 20;

Enter fullscreen mode Exit fullscreen mode

3. Temporal Dead Zone (TDZ):

What is the Temporal Dead Zone (TDZ)?

  • TDZ is the period between entering the scope and initializing let or const variables. Accessing them before declaration results in a ReferenceError.

Q: How does the TDZ affect the behavior of let and const?

  • They cannot be used until declared within their scope, preventing undefined or accidental accesses.

console.log(myVar); // ReferenceError due to TDZ
let myVar = 5;

Enter fullscreen mode Exit fullscreen mode

Q: What happens if you try to access a let or const variable before it’s declared?

  • It throws a ReferenceError.

4. Re-declaration and Re-assignment

Q: Can you re-declare a variable declared with let, const, or var?

  • var allows re-declaration; let and const do not within the same scope.

var x = 1;
var x = 2; // No error

let y = 1;
// let y = 2; // SyntaxError: Identifier 'y' has already been declared

Enter fullscreen mode Exit fullscreen mode

Q: What’s the difference between re-declaration and re-assignment in JavaScript?

  • Re-declaration: Declaring a variable again within the same scope.

  • Re-assignment: Changing the value of an existing variable.

Q: Can a const variable be re-assigned or mutated?

  • A const variable cannot be re-assigned. However, objects and arrays declared with const can be mutated.
const obj = { name: 'Alice' };
obj.name = 'Bob'; // Allowed (mutating the object)
// obj = { name: 'Charlie' }; // TypeError: Assignment to constant variable

Enter fullscreen mode Exit fullscreen mode

5. Practical Scenarios & Edge Cases

Q: What happens when var, let, and const variables are declared without an initial value?

  • var is initialized to undefined; let and const are uninitialized.

Q: How does block scoping with let and const work within loops?

  • let and const are block-scoped, so each loop iteration can have a new binding.
for (let i = 0; i < 3; i++) {
   setTimeout(() => console.log(i), 100); // Outputs 0, 1, 2
}

for (var j = 0; j < 3; j++) {
   setTimeout(() => console.log(j), 100); // Outputs 3, 3, 3}

Enter fullscreen mode Exit fullscreen mode

Q: What issues might arise if you use var in loops with asynchronous operations (like setTimeout)?

  • Using var in loops with asynchronous operations causes unexpected results due to lack of block scope.

6. Real-World Usage Questions

Q: Which keyword (let, const, or var) would you use for defining variables in a loop, and why?

  • Prefer let for variables that may change in each iteration to avoid scoping issues with var.

Q: It clarifies intent by ensuring values won’t change, making the code easier to follow.

  • It prevents re-assignment and maintains function immutability.
const greet = () => console.log('Hello!');

Enter fullscreen mode Exit fullscreen mode

Q: How can const improve code readability and maintainability?

  • It clarifies intent by ensuring values won’t change, making the code easier to follow.

7. Behavioral Questions and Scenarios

These focus on your understanding of var, let, and const and their behaviors in different contexts.

Q: What is the output of the following code, and why?

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

Enter fullscreen mode Exit fullscreen mode
  • Answer: undefined because var is hoisted and initialized with undefined. The declaration is moved to the top, but the assignment (x = 10) occurs in its original place.

Q: What about this code?

console.log(y); // ?
let y = 20;
Enter fullscreen mode Exit fullscreen mode
  • Answer: ReferenceError because let is hoisted but not initialized, leading to a Temporal Dead Zone (TDZ) until it is assigned a value.

Q: What happens if you declare a variable with const but don’t initialize it immediately?

const z; // ?

Enter fullscreen mode Exit fullscreen mode
  • Answer: SyntaxError. const must be initialized at the time of declaration.

8 Scope and Hoisting

Questions about scope test your understanding of how var, let, and const variables are accessible within functions, blocks, and globally.

Q: What will be logged to the console?

function scopeTest() {
   var a = 1;
   if (true) {
      let b = 2;
      const c = 3;
      console.log(a); // ?
      console.log(b); // ?
      console.log(c); // ?
   }
   console.log(a); // ?
   console.log(b); // ?
   console.log(c); // ?
}
scopeTest();

Enter fullscreen mode Exit fullscreen mode
  • Answer:

  • Inside the if block:

    • console.log(a) logs 1 because a is declared in the function scope and accessible within the block.
    • console.log(b) logs 2 because b is let-declared within the block.
    • console.log(c) logs 3 because c is const-declared within the block.
  • Outside the if block:

    • console.log(a) logs 1 because a is function-scoped.
    • console.log(b) and console.log(c) throw ReferenceErrors because b and c are block-scoped.

Q: How does the following code behave?

for (var i = 0; i < 3; i++) {
   setTimeout(() => console.log(i), 100);
}

Enter fullscreen mode Exit fullscreen mode
  • Answer: Logs 3 three times. Since var is function-scoped, each setTimeout refers to the same i variable, which has become 3 after the loop ends.

9 Re-assignment and Mutation

Questions related to re-assigning const and mutating objects or arrays help assess your understanding of immutability and value vs. reference.

Q: Can you re-assign a const variable? Why or why not?

  • Answer: No, re-assigning a const variable results in a TypeError. const variables cannot be re-assigned but can be mutated if they hold objects or arrays.

Q: What will happen in the following code?

const person = { name: 'Alice' };
person.name = 'Bob';
console.log(person); // ?

Enter fullscreen mode Exit fullscreen mode
  • Answer: { name: 'Bob' } because person is a reference to an object. const prevents re-assignment, not mutation of properties in the object.

10 Common Mistakes & Debugging

These questions test your understanding of variable declarations and common mistakes.

Q: Why does this code throw an error, and how would you fix it?

function check() {
   console.log(a); // ?
   let a = 10;
}
check();

Enter fullscreen mode Exit fullscreen mode

Answer: The code throws a ReferenceError due to the Temporal Dead Zone. To fix it, move the declaration let a = 10; above console.log(a);.

11 Practical Usage Scenarios

These questions test your ability to apply let, const, and var in real-world scenarios.

Q: When would you use let vs. const in a function or a loop?

  • Answer: Use const for values that don’t need to change and let for values that will change (e.g., loop counters or mutable values).

Q: Explain the output of this code:

const arr = [];
for (let i = 0; i < 3; i++) {
   arr.push(() => i);
}
console.log(arr.map(fn => fn())); // ?

Enter fullscreen mode Exit fullscreen mode
  • Answer: [0, 1, 2]. Each push creates a new i in the block scope of let, so each function holds the correct i value.

12 Edge Cases and Special Scenarios

These focus on unusual or complex cases involving variables.
Q: What happens if you declare a var variable twice in the same scope?

var x = 5;
var x = 10;
console.log(x); // ?

Enter fullscreen mode Exit fullscreen mode
  • Answer: 10. var allows re-declaration, so the last assignment takes effect.

Q: Explain why this code causes an error:

{
   console.log(myVar); // ?
   let myVar = 5;
}

Enter fullscreen mode Exit fullscreen mode
  • Answer: ReferenceError due to the Temporal Dead Zone. The variable myVar exists but cannot be accessed until its initialization line.

13 Shadowing

Q: What is variable shadowing, and how does it affect variable access?

  • Shadowing occurs when a variable declared within a certain scope (like a block or function) has the same name as a variable in an outer scope. The inner variable "shadows" the outer one, making the outer variable inaccessible in that scope.
let x = 'outer';
function shadowExample() {
   let x = 'inner';
   console.log(x); // 'inner'
}
shadowExample();
console.log(x); // 'outer'

Enter fullscreen mode Exit fullscreen mode

Q: Can you shadow a var variable with a let or const

  • Yes, let or const can shadow a var in a nested block.
var a = 'outer';
{
   let a = 'inner';
   console.log(a); // 'inner'
}
console.log(a); // 'outer'

Enter fullscreen mode Exit fullscreen mode

14 Closures and Variable Capture

Q: How do closures interact with variables declared with var, let, and const?

  • Closures capture the reference of variables, not the value. For example, using let in a loop with closures captures each iteration’s distinct value, whereas var captures only one value for the entire loop.
function closureTest() {
   let funcs = [];
   for (let i = 0; i < 3; i++) {
      funcs.push(() => console.log(i));
   }
   return funcs;
}
closureTest().forEach(fn => fn()); // Logs 0, 1, 2

function closureVarTest() {
   let funcs = [];
   for (var i = 0; i < 3; i++) {
      funcs.push(() => console.log(i));
   }
   return funcs;
}
closureVarTest().forEach(fn => fn()); // Logs 3, 3, 3

Enter fullscreen mode Exit fullscreen mode

In this code, we are using closures within a loop to see how let and var handle variable scope. Let’s walk through each case to understand the different outputs.
let Case: closureTest

function closureTest() {
   let funcs = [];
   for (let i = 0; i < 3; i++) {
      funcs.push(() => console.log(i));
   }
   return funcs;
}
closureTest().forEach(fn => fn()); // Logs 0, 1, 2

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Loop Scope with let: In this loop, i is declared using let, which is block-scoped. This means that each iteration of the loop creates a new instance of i with a unique value within that block.

  • Closures and let: When funcs.push(() => console.log(i)) runs, each function captures the current instance of i as a closure.

    • In the first iteration, i = 0, so the function captures 0.
    • In the second iteration, i = 1, so the function captures 1.
    • In the third iteration, i = 2, so the function captures 2.
  • Output: Each function, when called, has a distinct value for i (0, 1, and 2). Therefore, the output is 0, 1, and 2.

var Case: closureVarTest

function closureVarTest() {
   let funcs = [];
   for (var i = 0; i < 3; i++) {
      funcs.push(() => console.log(i));
   }
   return funcs;
}
closureVarTest().forEach(fn => fn()); // Logs 3, 3, 3

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Function Scope with var: When var is used to declare i, it is function-scoped rather than block-scoped. This means there is only one i shared across all iterations of the loop.

  • Closures and var: Each time funcs.push(() => console.log(i)) is executed, the function captures the reference to the same i variable.

    • After the loop completes, i has been incremented to 3 (the loop ends when i < 3 fails, so i becomes 3).
  • Output: Since each function in funcs holds a reference to the same i variable (now holding the value 3), each function logs 3 when called. Therefore, the output is 3, 3, 3.

Key Difference

  • let creates a new binding of i for each iteration due to block scoping, allowing each function to capture a unique value of i.
  • var only has one binding of i in the entire function scope, so all functions capture the same reference, which ends up being 3 after the loop completes.

To Summarize

  • Using let in the loop gives each iteration its own scoped variable, capturing the current value of i in each closure.
  • Using var in the loop results in all closures referencing the same variable, which has the final value after the loop (3 in this case).

15 Destructuring with let and const

Q: Can you use destructuring with let and const?

  • Yes. This is a common pattern, especially for working with arrays and objects. Destructuring with const works only when you don’t plan to reassign the variables.
const [a, b] = [1, 2];
console.log(a, b); // 1, 2

let { x, y } = { x: 10, y: 20 };
console.log(x, y); // 10, 20

Enter fullscreen mode Exit fullscreen mode

16 Temporal Dead Zone Edge Cases

Q: How does the TDZ apply to function arguments and default parameters?

  • The TDZ applies to any let or const variable, even when default parameter values reference other parameters.
function testTDZ(a = b, b = 1) {
   console.log(a, b);
}
// testTDZ(); // ReferenceError because `b` is not defined when `a` is assigned


Enter fullscreen mode Exit fullscreen mode

17 Global Variables and Global Scope Pollution

Q: What happens if you declare a variable without let, const, or var?

  • Declaring a variable without let, const, or var automatically places it in the global scope (in non-strict mode), which can lead to unintended side effects.
function globalExample() {
   someVar = 10; // Creates a global variable if in non-strict mode
}
globalExample();
console.log(someVar); // 10


Enter fullscreen mode Exit fullscreen mode

18 Best Practices Questions

Q: Why is it generally best practice to avoid using var in modern JavaScript code?

  • Using let and const is generally safer because they are block-scoped and prevent unexpected issues with hoisting and re-declaration.

Q: Why is const considered more readable and reliable for defining functions?

  • const ensures the function cannot be reassigned, which makes the code more predictable.

19 Advanced Temporal Dead Zone Questions

Q: Does the TDZ apply only within functions, or does it also apply to global and block scope?

  • The TDZ applies to any block, function, or global scope where let or const are declared. This means even globally declared variables are within the TDZ until they are initialized.
{
   console.log(temp); // ReferenceError
   let temp = 10;
}

Enter fullscreen mode Exit fullscreen mode

20 Default Parameters and const in Functions

Q: Can you use const within function parameters or with default values?

  • Yes, you can define function parameters with default values, but const cannot be used directly within the parameter list.
function sum(a, b = 10) {
   return a + b;
}

Enter fullscreen mode Exit fullscreen mode

21 Combining let and const with Conditional Statements

Q: What is the behavior of let and const declarations within if or try-catch blocks?

  • let and const are block-scoped, so they exist only within the block, even in if and try-catch statements.
if (true) {
   let blockVar = 'inside if';
   console.log(blockVar); // 'inside if'
}
console.log(blockVar); // ReferenceError

Enter fullscreen mode Exit fullscreen mode

you can follow me on GitHub

💖 💪 🙅 🚩
anikakash
Anik Dash Akash

Posted on November 5, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related