Nested Functions in JavaScript

Nested functions (or inner functions) in JavaScript are a useful feature. They are functions inside another function. Learn how to create a nested function. How variable scopes, closures & lexical scopes work. Also learn to create multi-level nested function, passing parameters to them etc

Nested Function

A nested function is a function inside another function

We can create the nested function in the same way we create the normal JavaScript function, But inside another function

In the following example, we create the logToConsole function inside the addNum function. We can invoke logToConsole just like any other function, but only inside the addNum function.

Variable Scope in Nested Function

The nested functions have their own scope. But they also have access to the parent functions scope. Hence you need to remember two important points.

  1. A nested function is private to containing function
  2. A nested function can access the containing function’s scope

Nested function is private to containing function

Only the containing function can access the nested function. We cannot access it anywhere outside the function. This is because the inner function is defined in the scope of the outer function (or containing function).

In the example below, we try to access the logToConsole from the outside of the addNum function. But It will result in an error.

Nested function can access the containing functions scope

The nested function can access all variables, functions & arguments defined in the containing function. This ability where the inner function can access the parent function scope is known as Lexical scope

In the example, we do not pass any value to logToConsole. Inside the nested function, we can access both arguments of the containing function i.e. a & b, and also the result variable.

Returning a Nested Function

The container function can return the nested function. In the following example, the makeCounter initializes the count property and returns the increment function. We store the inner function in the counter property

Whenever we invoke the counter it will increment the count and return the result. What makes it interesting here is that the increment function can still access the count property of the makeCounter, although the makeCounter function finished its execution. This works because of a JavaScript feature known as Closure

Closure

The count property is local to the makeCounter function. The increment function can access it because it is nested inside the makeCounter function.

In this line of code, we invoke the makeCounter, which initializes the count to 0 and returns the increment function.

Usually, we expect JavaScript to clean up the memory when the function returns. But in the example above, we return the inner function which needs to access the count property of makeCounter function. Cleaning up the memory will make the count property inaccessible to the inner function.

In such cases, JavaScript keeps the memory alive and attaches it to the inner function. This is called closure. The JavaScript keeps this in memory as long as someone has reference to the increment function.

Hence, when we invoke the increment function using the counter variable, it will increment the count property. Because the count property is not destroyed and still in memory.

In this example, we invoke makeCounter twice. Each call to makeCounter will get its own memory and count property. Because of this each of returned nested functions gets its own copy of the count property. Hence they do not interfere with each other.

Returning a new object with a nested function

In the following example, the function does not contain a nested function but returns an object, which contains a function. Technically the function inside the object is also a nested function. It can also access the properties of its parent function i.e. makeCounter

Parameters in nested function

You can also pass arguments to inner function. In the following example, outerfunc returns the innerFunc. Both accepts a parameters

The code InnerFunc=outerfunc(5) returns the inner function. You can invoke it as nnerFunc(3)

Another way to invoke the inner function is using the outerfunc(10)(2)

Mulitple levels of Nesting

We can also create multiple levels of nested functions in JavaScript. The following code is a 3 level nested function.

  • outerFunc contains a function InnerFunc, which itself contains a function innermostFunc.
  • outerFunc can invoke innerFunc. But cannot invoke innermostFunc
  • innerFunc can access the properties & methods of outerFunc
  • innermostFunc can access innerFunc. It can also access the outerFunc

The Important point to note here is that innermostFunc can access the outerFunc. This is because the scopes are recursive. The innermostFunc contains the scope of the innerFunc. The innerFunc contains the scope of outerFunc. This is called scope chaining.

Name conflicts

We run into name conflict when two functions define the same variable. For Example in the following example innerFunc defines variable a. Hence it will hide the a variable of the outerfunc. Hence the innermostFunc will also see the variable from the innerFunc because that is its immediate parent.

Leave a Comment

Your email address will not be published.

Scroll to Top