Function declaration vs expression
Explains hoisting differences between declarations and expressions.
function declared() { /* ... */ }
const expressed = function () { /* ... */ };
const arrowed = () => { /* ... */ };This static page keeps the syntax and examples indexed for search, while the coding app handles interactive exploration and saved references.
What it does
Overview
Explains hoisting differences between declarations and expressions.
Function declarations are hoisted in their entirety during the compilation phase, allowing them to be invoked anywhere within their containing scope, even before their actual definition in the source code. Function expressions, however, are only initialized when the execution flow reaches the assignment statement. If defined with 'const' or 'let', they reside in the Temporal Dead Zone (TDZ) until that point; if defined with 'var', the variable is hoisted as 'undefined', leading to a TypeError if called early. Performance-wise, function declarations are slightly more efficient for engines to optimize during the initial script parse. A critical edge case involves block-level scoping: in ES6 strict mode, function declarations are scoped to the block they are defined in, whereas in non-strict mode, behavior can vary across engines. Arrow functions, a modern form of function expression, do not create their own 'this' context, making them unsuitable for object methods requiring 'this' or as constructors.
Quick reference
Syntax
function declared() { /* ... */ }
const expressed = function () { /* ... */ };
const arrowed = () => { /* ... */ };
See it in practice
Examples
Function Declaration Hoisting
console.log(calculateArea(5, 10));
function calculateArea(width, height) {
return width * height;
}50
The entire function definition is moved to the top of the scope by the JS engine, allowing successful execution before the line of definition.
Function Expression with TDZ
try {
console.log(multiply(2, 3));
} catch (e) {
console.log(e.name);
}
const multiply = function(a, b) {
return a * b;
};
console.log(multiply(2, 3));ReferenceError 6
Variables declared with const are not initialized until the line is reached. Accessing them early triggers a ReferenceError.
Anonymous Expressions as Callbacks
var numbers = [1, 2, 3];
var squared = numbers.map(function(n) {
return n * n;
});
console.log(squared);[1, 4, 9]
Function expressions are commonly used as arguments (callbacks) where a named declaration is unnecessary.
Debug faster
Common Errors
TypeError
Cause: Attempting to call a function expression defined with 'var' before the assignment occurs.
Fix: Move the function call after the assignment or use a function declaration.
console.log(doWork());
var doWork = function() { return 'done'; };ReferenceError
Cause: Calling a function expression defined with 'const' or 'let' before its definition line.
Fix: Ensure all 'const' function expressions are defined at the top of the script or before their first use.
startApp();
const startApp = () => { console.log('Starting...'); };Runtime support
Compatibility
Source: MDN Web Docs
Common questions
Frequently Asked Questions
Explains hoisting differences between declarations and expressions.
TypeError: Move the function call after the assignment or use a function declaration. ReferenceError: Ensure all 'const' function expressions are defined at the top of the script or before their first use.