Inner Functions
In JavaScript, you can define functions inside other functions. That is useful when you need a helper function that is only used inside one specific function. Inner functions are also what closures are built on, and we will get to closures in the next section.
How Inner Functions Work
Let’s look at a simple example where one function is nested inside another:
function outer() {
let a = 1;
function inner() {
let a = 2;
let b = 3;
console.log(a); // 2
console.log(b); // 3
}
inner();
console.log(a); // 1
console.log(b); // ReferenceError: b is not defined
}
outer();
In this example, outer is a function that contains another function inner. The inner function has its own scope. Variables declared inside inner are not accessible from outer.
Accessing Outer Variables
Inner functions can access and modify variables from their parent function:
function outer() {
let num = 1;
function inner() {
num++;
}
console.log(num); // 1
inner();
console.log(num); // 2
}
outer();
Here, the inner function modifies the num variable defined in outer. This ability to access variables from an enclosing scope is what makes closures possible.
When to Use Inner Functions
Inner functions are useful for:
- Helper functions: Keep utility functions private to the function that needs them
- Organizing complex logic: Break down a large function into smaller, focused pieces
- Preparing for closures: When you need to return a function that still uses the outer function’s variables
function processData(data) {
// Helper function only needed here
function validate(item) {
return item !== null && item !== undefined;
}
// Helper function only needed here
function transform(item) {
return item.toString().toUpperCase();
}
return data.filter(validate).map(transform);
}
console.log(processData(["hello", null, "world"])); // ["HELLO", "WORLD"]
By nesting validate and transform inside processData, we keep them private and avoid adding functions to the outer scope that are not needed elsewhere.
In the next section, we will see what happens when an inner function is returned and used outside its parent function. This is how closures work.