[Medium] π Hoisting
1. What's Hoisting ?β
JavaScript execution can be viewed as two phases: creation and execution.
var name = 'Pitt';
console.log(name); // print Pitt
With hoisting, the engine conceptually handles declaration first and assignment later:
// create
var name;
// execute
name = 'Pitt';
console.log(name);
Functions behave differently from variables. A function declaration is bound during the creation phase:
getName();
function getName() {
console.log('string'); // print string
}
This works because the function declaration is hoisted before runtime calls:
// create
function getName() {
console.log('string');
}
// execute
getName();
Note: with function expressions, declaration and assignment order still matters.
In the creation phase, function declarations have higher priority than variable declarations.
Correctβ
name = 'Yumy';
console.log(name); // print Yumy
var name;
// --- Equal to ---
// create
var name;
// execute
name = 'Yumy';
console.log(name); // print Yumy
Wrongβ
console.log(name); // print undefined
var name = 'Jane';
// --- Equal to ---
// create
var name;
// execute
console.log(name); // print undefined, because assignment has not happened yet
name = 'Pitt';
2. What's name printed ?β
whoseName();
function whoseName() {
if (name) {
name = 'Nini';
}
}
var name = 'Pitt';
console.log(name);
Answerβ
// create
function whoseName() {
if (name) {
name = 'Nini';
}
}
var name;
// execute
whoseName();
name = 'Pitt';
console.log(name); // print Pitt
Inside whoseName(), name starts as undefined, so the if (name) branch does not run.
After that, name gets assigned 'Pitt', so the final output is still Pitt.
3. Function Declaration vs Variable Declaration: Hoisting Priorityβ
Question: function and variable with the same nameβ
Predict the output of this code:
console.log(foo);
var foo = '1';
function foo() {}
Common wrong answersβ
Many people think it will:
- Output
undefined(assumingvaris hoisted first) - Output
'1'(assuming assignment already took effect) - Throw an error (assuming same-name conflict)
Actual outputβ
[Function: foo]
Why?β
This question tests the hoisting priority rule:
Hoisting priority: function declaration > variable declaration
// Original code
console.log(foo);
var foo = '1';
function foo() {}
// Equivalent after hoisting
// Phase 1: creation (hoisting)
function foo() {} // 1. function declaration is hoisted first
var foo; // 2. variable declaration is hoisted (does not overwrite function)
// Phase 2: execution
console.log(foo); // foo is a function here
foo = '1'; // 3. assignment overwrites function
Key Conceptsβ
1. Function declarations are fully hoisted
console.log(myFunc); // [Function: myFunc]
function myFunc() {
return 'Hello';
}
2. var hoists declaration only, not assignment
console.log(myVar); // undefined
var myVar = 'Hello';
3. When function and variable declarations share a name
// Hoisted order
function foo() {} // function is hoisted and initialized first
var foo; // declaration hoisted, but does not overwrite function
// Therefore foo is still a function
console.log(foo); // [Function: foo]
Full Execution Flowβ
// Original code
console.log(foo); // ?
var foo = '1';
function foo() {}
console.log(foo); // ?
// ======== Equivalent ========
// Creation phase (hoisting)
function foo() {} // 1οΈβ£ function declaration is fully hoisted
var foo; // 2οΈβ£ variable declaration is hoisted but does not replace function
// Execution phase
console.log(foo); // [Function: foo]
foo = '1'; // 3οΈβ£ assignment now overwrites function
console.log(foo); // '1'
Extended Questionsβ
Question A: does order change the result?β
console.log(foo); // ?
function foo() {}
var foo = '1';
console.log(foo); // ?
Answer:
[Function: foo] // first output
'1' // second output
Reason: source order does not change hoisting priority. Function declaration still wins over variable declaration in creation phase.
Question B: multiple functions with the same nameβ
console.log(foo); // ?
function foo() {
return 1;
}
var foo = '1';
function foo() {
return 2;
}
console.log(foo); // ?
Answer:
[Function: foo] // first output (later function declaration overrides earlier one)
'1' // second output (assignment overrides function)
Reason:
// After hoisting
function foo() {
return 1;
} // first function
function foo() {
return 2;
} // second function overrides first
var foo; // declaration only (does not overwrite function)
console.log(foo); // function returning 2
foo = '1'; // assignment overwrites function
console.log(foo); // '1'
Question C: function expression vs function declarationβ
console.log(foo); // ?
console.log(bar); // ?
var foo = function () {
return 1;
};
function bar() {
return 2;
}
Answer:
undefined // foo is undefined
[Function: bar] // bar is a function
Reason:
// After hoisting
var foo; // variable declaration is hoisted (function body is not)
function bar() {
return 2;
} // function declaration is fully hoisted
console.log(foo); // undefined
console.log(bar); // function
foo = function () {
return 1;
}; // assignment at runtime
Key difference:
- Function declaration:
function foo() {}-> fully hoisted (including body) - Function expression:
var foo = function() {}-> only variable name is hoisted
let/const avoid this patternβ
// β `var` has hoisting pitfalls
console.log(foo); // undefined
var foo = '1';
// β
let/const are in TDZ before initialization
console.log(bar); // ReferenceError
let bar = '1';
// β
using same name with function and let/const throws
function baz() {}
let baz = '1'; // SyntaxError: Identifier 'baz' has already been declared
Hoisting Priority Summaryβ
Hoisting priority (high -> low):
1. Function Declaration
- function foo() {} β
fully hoisted
- highest priority
2. Variable Declaration
- var foo β οΈ declaration only (no assignment)
- does not overwrite existing function declaration
3. Variable Assignment
- foo = '1' β
can overwrite function
- happens only in execution phase
4. Function Expression
- var foo = function() {} β οΈ treated as assignment
- only variable name is hoisted
Interview Focusβ
When answering this type of question, you can follow this structure:
- Explain hoisting as two phases: creation and execution.
- Emphasize priority: function declaration > variable declaration.
- Rewrite the code into the hoisted form to show reasoning.
- Mention best practices: prefer
let/const, and avoid confusingvarpatterns.
Sample interview answer:
This question is about hoisting priority. In JavaScript, function declarations are hoisted before variable declarations.
The engine goes through two phases:
- Creation phase:
function foo() {}is hoisted first, thenvar foois hoisted without overwriting the function.- Execution phase:
console.log(foo)prints the function, and only laterfoo = '1'overwrites it.In practice, use
let/constinstead ofvarto avoid this confusion.