Last updated: Mar 4, 2024
Reading timeยท3 min
To call a function inside another function, define the inner function inside the outer function and invoke it.
When using the function
keyword, the function gets hoisted to the top of the
scope and can be called from anywhere inside the outer function.
function outerFunc(a, b) { function innerFunc(a, b) { return a + b; } const result = innerFunc(a, b); return result; } console.log(outerFunc(10, 10)); // ๐๏ธ 20 console.log(outerFunc(10, 20)); // ๐๏ธ 30
The following example shows how we can call the inner function before it is declared.
This is because of how hoisting works in JavaScript.
function outerFunc() { const num1 = 5; const num2 = 10; // ๐๏ธ call inner function before it's declared const result = innerFunc(); function innerFunc() { return num1 + num2; } return result; } console.log(outerFunc()); // ๐๏ธ 15
This only works for functions declared using the function
keyword (not for
arrow functions).
An alternative approach is to return the inner function from the outer one.
function outerFunc() { function innerFunc(a, b) { return a + b; } return innerFunc; } const innerFunc = outerFunc(); console.log(innerFunc(2, 3)); // ๐๏ธ 5 console.log(innerFunc(3, 3)); // ๐๏ธ 6
Notice that we didn't use parentheses ()
to invoke the inner function inside
the outer one.
We returned the function without invoking it. In other words, we returned a reference to the inner function, not the result of calling it.
What's most useful in this scenario is that the inner function remembers the variables declared in the outer function between invocations.
function outerFunc() { const z = 100; function innerFunc(a, b) { return a + b + z; } return innerFunc; } const innerFunc = outerFunc(); console.log(innerFunc(2, 3)); // ๐๏ธ 105 console.log(innerFunc(3, 3)); // ๐๏ธ 106
Notice that the inner function remembers the value of the z
variable between
invocations.
This concept is called a closure in JavaScript.
The inner function gets bundled with references to its surrounding state.
This is useful in many different scenarios. For example, you could pass a parameter to the outer function that it will remember for any of the inner function calls.
function outerFunc(a) { function innerFunc(b, c) { return a + b + c; } return innerFunc; } const innerFunc = outerFunc(10); console.log(innerFunc(1, 1)); // 12 console.log(innerFunc(1, 2)); // 13
We passed 10
as a parameter to the outer function and stored the result in a
variable.
The innerFunc
variable stores a reference to the innerFunc
function where
the a
variable points to a value of 10
.
Now we can omit 10
from the parameters when calling the inner function.
You can also return an object from the outer function.
function outerFunc() { function innerFunc(a, b) { return a + b; } return {innerFunc}; } const outer = outerFunc(); console.log(outer.innerFunc(10, 10)); // 20 console.log(outer.innerFunc(20, 15)); // 35
The object contains a single property - the inner function.
You can call the inner function by accessing the property on the object.
I've written a detailed article on how to call a function in an object.