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
andconst
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, whereasconst
creates a constant reference.
var a = 10;
let b = 20;
const c = 30;
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
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
andconst
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
}
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
}
Q: How does scope differ between var
, let
, and const
?
-
var
has function scope;let
andconst
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 withundefined
.let
andconst
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;
3. Temporal Dead Zone (TDZ):
What is the Temporal Dead Zone (TDZ)?
- TDZ is the period between entering the scope and initializing
let
orconst
variables. Accessing them before declaration results in aReferenceError
.
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;
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
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 withconst
can be mutated.
const obj = { name: 'Alice' };
obj.name = 'Bob'; // Allowed (mutating the object)
// obj = { name: 'Charlie' }; // TypeError: Assignment to constant variable
5. Practical Scenarios & Edge Cases
Q: What happens when var
, let
, and const
variables are declared without an initial value?
-
var
is initialized toundefined
;let
andconst
are uninitialized.
Q: How does block scoping with let
and const
work within loops?
-
let
andconst
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}
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 withvar
.
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!');
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;
-
Answer: undefined because
var
is hoisted and initialized withundefined
. 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;
-
Answer:
ReferenceError
becauselet
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; // ?
-
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();
Answer:
-
Inside the
if
block:-
console.log(a)
logs1
becausea
is declared in the function scope and accessible within the block. -
console.log(b)
logs2
becauseb
islet
-declared within the block. -
console.log(c)
logs3
becausec
isconst
-declared within the block.
-
-
Outside the
if
block:-
console.log(a)
logs1
becausea
is function-scoped. -
console.log(b)
andconsole.log(c)
throwReferenceError
s becauseb
andc
are block-scoped.
-
Q: How does the following code behave?
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
-
Answer: Logs
3
three times. Sincevar
is function-scoped, eachsetTimeout
refers to the samei
variable, which has become3
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); // ?
-
Answer:
{ name: 'Bob' }
becauseperson
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();
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 andlet
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())); // ?
-
Answer:
[0, 1, 2]
. Eachpush
creates a newi
in the block scope oflet
, 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); // ?
-
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;
}
- 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'
Q: Can you shadow a var variable with a let or const
- Yes,
let
orconst
can shadow avar
in a nested block.
var a = 'outer';
{
let a = 'inner';
console.log(a); // 'inner'
}
console.log(a); // 'outer'
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, whereasvar
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
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
Explanation:
Loop Scope with
let
: In this loop,i
is declared usinglet
, which is block-scoped. This means that each iteration of the loop creates a new instance ofi
with a unique value within that block.-
Closures and
let
: Whenfuncs.push(() => console.log(i))
runs, each function captures the current instance ofi
as a closure.- In the first iteration,
i = 0
, so the function captures0
. - In the second iteration,
i = 1
, so the function captures1
. - In the third iteration,
i = 2
, so the function captures2
.
- In the first iteration,
Output: Each function, when called, has a distinct value for
i
(0
,1
, and2
). Therefore, the output is0
,1
, and2
.
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
Explanation:
Function Scope with
var
: Whenvar
is used to declarei
, it is function-scoped rather than block-scoped. This means there is only onei
shared across all iterations of the loop.-
Closures and
var
: Each timefuncs.push(() => console.log(i))
is executed, the function captures the reference to the samei
variable.- After the loop completes,
i
has been incremented to3
(the loop ends wheni < 3
fails, soi
becomes3
).
- After the loop completes,
Output: Since each function in
funcs
holds a reference to the samei
variable (now holding the value3
), each function logs3
when called. Therefore, the output is3, 3, 3
.
Key Difference
-
let
creates a new binding ofi
for each iteration due to block scoping, allowing each function to capture a unique value ofi
. -
var
only has one binding ofi
in the entire function scope, so all functions capture the same reference, which ends up being3
after the loop completes.
To Summarize
- Using
let
in the loop gives each iteration its own scoped variable, capturing the current value ofi
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
16 Temporal Dead Zone Edge Cases
Q: How does the TDZ apply to function arguments and default parameters?
- The TDZ applies to any
let
orconst
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
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
, orvar
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
18 Best Practices Questions
Q: Why is it generally best practice to avoid using var
in modern JavaScript code?
- Using
let
andconst
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
orconst
are declared. This means even globally declared variables are within the TDZ until they are initialized.
{
console.log(temp); // ReferenceError
let temp = 10;
}
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;
}
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
andconst
are block-scoped, so they exist only within the block, even inif
andtry-catch
statements.
if (true) {
let blockVar = 'inside if';
console.log(blockVar); // 'inside if'
}
console.log(blockVar); // ReferenceError
Top comments (0)