Back to: JavaScript Tutorial For Beginners and Professionals
JavaScript Recursive Functions with Examples
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
Recursion with Function Expression
Recursion is simple enough with function declarations. But not so easy with function expressions
- Call function
- Assign the function to a variable
- 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
- Global scope is the same for the whole web page
- 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:
- They are defined outside of a function scope
- 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
- It’s all about scope!
- There is No limitation of the level of nesting
- Objects can access the scope they are in (also called closure)
- 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 JavaScript Recursive Functions with Examples article will helps you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this article.