JavaScript Recursive Function

JavaScript Recursive Functions

In this article, I am going to discuss JavaScript Recursive Functions with Examples. Please read our previous article where we discussed Function Expressions in JavaScript. At the end of this article, you will understand the What are JavaScript Recursive Functions and when and how to create and use Recursive functions in JavaScript with examples.

What is Recursion?

Calling function from themselves. Recursion is when a function calls itself. A powerful programming technique. May be direct or indirect.

Recursion works quite well when Traversing non-linear data structures such as Trees, matrices, graphs, DOM nodes. When Generating combinations / variations / permutations / … or Generating sequences: Fibonacci, factorial.

Every recursion can be replaced by enough loops. Also called iterative solution. Yet, in some cases using recursion is simpler than using loops

Example:

<html>
<head>
</head>
<body>
    <script type="text/javascript">
        function factorial(n) {
            if (n == 0) {
                return 1;
            }
            return factorial(n - 1) * n;            
        }   
        console.log(factorial(5));
    </script>
    <form>
        <input type="button" value="click" onclick="factorial(5)" />
    </form>
</body>
</html>

Output: 120

Recursion: Factorial

Using recursion to calculate factorial numbers. Using the formula F(N) = F(N-1) * N

Example:

function factorial(n) {
            if (n == 0) {
                return 1;
            }
            return factorial(n - 1) * n;
        }
        console.log(factorial(5));  // 120
        console.log(factorial(12)); // 479001600
Traversing the DOM Recursively

For each element print its tag name and invoke the same function recursively for each of its children

Example:

function traverse(node) {
            traverseNode(node, '');
            function traverseNode(node, spacing) {
                spacing = spacing || '  ';
                console.log(spacing + node.nodeName);
                for (var i = 0, len = node.childNodes.length; i < len; i += 1) {
                    var child = node.childNodes[i];
                    if (child.nodeType === document.ELEMENT_NODE) {
                        traverseNode(child, spacing + '  ');
                    }
                }
                console.log(spacing + '/' + node.nodeName);
            }
        }
DOM Traversal

JavaScript Recursive Functions

Recursion with Function Expression

Recursion is simple enough with function declarations. But not so easy with function expressions

  1. Call function
  2. Assign the function to a variable
  3. Assign a number value to the original function

Example:

var fact = function (n) {
            if (n === 0) {
                return 1;
            }
            return n * fact(n - 1);
        };
console.log(fact(5));

Output: 120

The previous example can be solved by giving an identifier to the function expression. Only the function itself can use this identifier

Example:

var factorial = function factorial(n) {
if (n == 1) {
return 1;
}
return n * factorial(n - 1);
//or use arguments.callee
};
var factorial2 = factorial;
factorial = 5;
console.log(factorial2(5)); // prints 120  correct
Variable Scope in JavaScript

Scope is a place where variables are defined and can be accessed. JavaScript has only two types of scopes

  1. Global scope is the same for the whole web page
  2. Function scope is different for every function

Everything outside of a function scope is inside of the global scope

Example:

if (true) {
var sum = 1 + 2;
}
console.log(sum); // logs: 3
Global Scope

The global scope is the scope of the web page. Objects belong to the global scope if:

  1. They are defined outside of a function scope
  2. They are defined without var (fixable with ‘use strict’)

Example:

function arrJoin(arr, separator) {
            separator = separator || "";
            arr = arr || [];
            arrString = "";
            for (var i = 0; i < arr.length; i += 1) {
                arrString += arr[i];
                if (i < arr.length - 1) arrString += separator;
            }
            return arrString;
        }
Function Scope

JavaScript does not have a block scope like other programming languages (C#, Java, C++). { and } does not create a scope!. Yet, JavaScript has a function scope. Function expressions and function declarations create scope

if (true) { var result = 5; }
console.log(result); // logs 5

if (true) (function () { var result = 5; })();
console.log(result); // ReferenceError

function logResult() { var result = 5; }
if (true) logResult();
console.log(result); // ReferenceError
Nested Functions in JavaScript

Functions in JavaScript can be nested

  1. It’s all about scope!
  2. There is No limitation of the level of nesting
  3. Objects can access the scope they are in (also called closure)
  4. The inner scope can access everything above it

Example:

function compare(str1, str2, caseSensitive) {
            if (caseSensitive) { return compareCaseSensitive(str1, str2); }
            else { return compareCaseInsesitive(str1, str2); }

            function compareCaseSensitive(str1, str2) { … };
            function compareCaseInsesitive(str1, str2) { … };
        }
Nested Functions: Example

Objects can access the scope they are in. outer() can access the global scope. inner1() can access the scope of outer() scope. And through outer() – can access the global scope and etc…

var str = "I am happy";          //global scope
        function outer(o1, o2) {         //outer scope
            function inner1(i1, i2, i3) {  //inner1 scope
                function innerMost(im1) {    //innerMost scope
                    …
                }                            //end of innermost scope
            }                              //end of inner1 scope
            function inner2(i1, i2, i3) {  //inner2 scope
                …
            }                              //end of inner2 scope
        }                                //end of outer scope
        var number = 1;
Nested Functions and Scope

What about objects with the same name? If in the same scope – the bottommost object. If not in the same scope – the object in the innermost scope

Example:

function compare(str1, str2, caseSensitive) {
            if (caseSensitive) return compareCaseSensitive(str1, str2);
            else return compareCaseInsesitive(str1, str2);

            function compareCaseSensitive(str1, str2) {
                // here matter str1 and str2 in compareCaseSensitive 
            }
            function compareCaseInsesitive(str1, str2) {
                // here matter str1 and str2 in compareCaseInsensitive
            }
        }
Closures

Function that refers to independent (free) variables. Closures are a special kind of structure. They combine a function and the context of this function. Function defined in the closure ‘remembers’ the environment in which it was created

Example:

function outer(x) {
            function inner(y) {
                return x + " " + y;
            }
            return inner;
        }

In the above example inner() forms a closure. It holds a reference to x.

var f1 = outer(5);
console.log(f1(7)); // outputs 5 7

In the above example it’s a self-explanatory that in the context of f1, x has value 5.

var f2 = outer(“Shagufta”);
console.log(f2(“closure”)); // outputs shagufta closure

In the above in the context of f2, x has value “Shagufta”

Closures Usage

Closures can be used for data hiding (encapsulation in OOP). Make objects invisible to the outside (private)

Example:

var school = (function () {
           var students = [];
           var teachers = [];
           function addStudent(name, grade) {... }
           function addTeacher(name, speciality) {... }
           function getTeachers(speciality) {... }
           function getStudents(grade) {... }
           return {
               addStudent: addStudent,
               addTeacher: addTeacher,
               getTeachers: getTeachers,
               getStudents: getStudents
           };
       })();
Function Hoisting

Hoisting is JavaScript’s default behavior of moving declarations to the top of the current scope. Hoisting applies to variable declarations and to function declarations also. Because of this, JavaScript functions can be called before they are declared:

Example:

myTest(5);
        function myTest(y) {
            return y * y;
        }

Functions defined using an expression are not hoisted.

In the next article, I am going to discuss JavaScript Popup Boxes with examples. Here, in this article, I try to explain JavaScript Recursive Functions and Nested Functions with examples. I hope this article will helps you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *