Why JavaScript Function Declarations Behave Differently Than Expressions
This article explains the crucial differences between JavaScript function declarations and function expressions, how hoisting affects their availability, and why misunderstanding these concepts can lead to unexpected bugs in your code.
JavaScript functions are everywhere and powerful, allowing object‑oriented features such as encapsulation and inheritance, but they can also create subtle bugs if their behavior is not fully understood.
1) Function Declaration
function funDeclaration(type){
return type==="Declaration";
}2) Function Expression
var funExpression = function(type){
return type==="Expression";
}Although the two snippets look similar, the way JavaScript treats them is fundamentally different. A function declared with a declaration can be called before its definition because the declaration is hoisted during the parsing phase.
1 funDeclaration("Declaration"); // => true
2 function funDeclaration(type){
3 return type==="Declaration";
4 }In contrast, a function created with an expression is assigned at runtime; it cannot be invoked before the assignment occurs.
1 funExpression("Expression"); // => error
2 var funExpression = function(type){
3 return type==="Expression";
4 }The underlying reason is that function declarations are hoisted, while function expressions are evaluated only when the execution reaches the assignment statement.
The following diagram illustrates the hoisting behavior of the two code blocks:
To deepen the distinction, consider a more confusing example:
var sayHello;
console.log(typeof (sayHey)); // => function
console.log(typeof (sayHo)); // => undefined
if (true) {
function sayHey() {
console.log("sayHey");
}
sayHello = function sayHo() {
console.log("sayHello");
}
} else {
function sayHey() {
console.log("sayHey2");
}
sayHello = function sayHo() {
console.log("sayHello2");
}
}
sayHey(); // => sayHey2
sayHello(); // => sayHelloAnalysis: sayHey is a function declaration, so during parsing both sayHey definitions are hoisted; the second one overwrites the first, resulting in sayHey2 being logged. sayHello is a function expression; its assignment happens at runtime, so the first definition is used.
The code above is equivalent to the following simplified version:
var sayHello;
function sayHey() {
console.log("sayHey");
}
function sayHey() {
console.log("sayHey2");
}
if (true) {
// hoisting...
sayHello = function sayHo() {
console.log("sayHello");
}
} else {
// hoisting...
sayHello = function sayHo() {
console.log("sayHello2");
}
}
sayHey(); // => sayHey2
sayHello(); // => sayHelloIn summary, function declarations are hoisted and can be invoked anywhere within their scope, while function expressions are evaluated at runtime and become callable only after the assignment has executed. This subtle difference can easily introduce hard‑to‑detect bugs.
Below are visual step‑by‑step diagrams of the execution flow for sayHello and sayHey:
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
