Scope in Nested Functions

Contact Us or call 1-877-932-8228
Scope in Nested Functions

Scope in Nested Functions

Variables created with the var keyword are, as we have seen, scoped to their enclosing function. A function defined inside of another function has access to variables created in the parent function. Here's an example:

Code Sample:

Scope/Demos/functionsinsidefunctions.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Scope: Functions inside Functions</title>
	<script>
		var v0 = 0;
		//accessible here: v0
		function fun1() {
			var v1 = 7;
			//accessible here: v0, v1
			function fun2() {
				var v2 = 26;
				//accessible here: v0, v1, v2
				function fun3() {
					var v3 = 234;
					//accessible here: v0, v1, v2, v3
				}
				fun3();
				//accessible here: v0, v1, v2
			}
			fun2();
			//accessible here: v0, v1
		}
	</script>
</head>
<body>
	<h1>Scope: Functions inside Functions</h1>
	<script>
		fun1();
		//accessible here: v0
	</script>
</body>
</html>

Code Explanation

We define a function fun1(), define function fun2() inside of fun1() and define function fun3() inside of fun2().

Variable v0, declared outside of any function, is global - we can access it anywhere. Because variable v1 is declared inside of function fun1(), v1 is accessible anywhere inside of function fun1() - including inside of functions fun2() and fun3() (which are declared inside of fun1()).

Variable v2 is accessible to functions fun2() and fun3() but not fun1(). Similarly, variable v3 is only accessible inside of fun3() but not to any of the "outer" functions.

Scope and nested anonymous nested functions offer some interesting possibilities in JavaScript, both for potential errors and for writing code (closures) that offers protection against unwanted errors. We'll dive deeply into closures later in this course; let's look now at some curious effects of execution context and functions - consider the following example:

Code Sample:

Scope/Demos/nestedanonymousfunction.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Nested Anonymous Function Example</title>
	<script>
		function createIDs(arr) {
		    var startingVal = 10;
		    for (var p=0; p<arr.length; p++) {
		      	arr[p]["UID"] = function() {
		      		return startingVal + p;
		      	}
		    }
		    return arr;
		}
	</script>
</head>
<body>
	<h1>Nested Anonymous Function Example</h1>
	<script>
		var people = [
						{fname:"Jane",lname:"Doe",UID:0},
					 	{fname:"Carly",lname:"Gutierrez",UID:0},
					 	{fname:"James",lname:"Chan",UID:0}
					 ];
		var peopleWithUniqueIDs = createIDs(people);
		for (var i=0; i<peopleWithUniqueIDs.length; i++) {
			document.write(peopleWithUniqueIDs[i]["fname"] + ' ' + peopleWithUniqueIDs[i]["fname"] + ", ID: " + peopleWithUniqueIDs[i].UID());
			document.write('<hr>');
		}
	</script>
</body>
</html>

Code Explanation

In our code, we create a JavaScript array of hashes people; each element of the array has fields fname ("first name"), lname ("last name"), and UID ("unique ID"); when created, each UID field is not unique, assigned a default value 0.

We create a function createIDs, whose job is to assign the unique IDs. We use what might at first appear to be a curious pattern here: iterating over the array (via a for loop), we assign each UID field to be the returned result of an anonymous function. The function ("anonymous" because it has no name) returns the sum of startingVal (given value 10 when initialized in function createIDs) and p, the for-loop counter variable.

We invoke function createIDs, passing array people to it, and store the result in array peopleWithUniqueIDs. When we iterate over the new array and write its values to the screen, we can call the anonymous function to get the calculated value of the UID field, with the code peopleWithUniqueIDs[i].UID(). The results may be surprising:

output from nested anonymous functions demo

We might expect that each UID field would get a unique value (10, 11, and 12) since the for loop variable takes on values 0, 1, and 2. But the anonymous function - that is, the function we call when we write the code peopleWithUniqueIDs[i].UID() - has access to the variables in function createIDs and, since that function has already run, the value of p (the for-loop counter variable) is 3.

Next