Scope of Variables and Arguments in Nested JavaScript Functions
In this part of the series we shall look at the scope of variables and arguments in nested functions. We shall see whether the outer function can use the variables and arguments of the inner functions and vice versa. We shall also see how many levels downward or upward this can be done.
Scope of Variables and Arguments in Nested JavaScript Functions - Argument Scope within Nested Functions (Page 2 of 4 )
Before we talk about the argument scope within nested functions, let us first talk about JavaScript’s argument’s array, which we shall use for the explanation.
JavaScript’s Argument’s Array
This is an array having the arguments passed into a function. The elements in this array, from index zero to index (arguments.length – 1) are the arguments sent into the function, as you see in the () brackets, from left to right. Inside the function, this arguments array acts like an internal variable with the name “arguments.”
Now, functions in JavaScript are informal objects. So arguments which are an array are a property of any function. JavaScript creates it for you; you do not have to create it. With nested functions, it acts like a property of the nested function.
Let us look at examples. In the first example we shall address the arguments array inside a function. In the second example, we shall address the array of a function from its nested function.
There is an HTML button. When you click the button, the ourFunction() function is called. The arguments passed into this function are "one," "two" and "three." So the first element of the array is "one," the second is "two" and the third is "three."
The first statement in the function is “alert(arguments[0]);”, the second statement is “alert(arguments[1]);” and the third statement is, “alert(arguments[2]);”. Note how we have addressed the elements of the array. We have addressed them as we would address the element of the array whose name is “arguments.”
If you try this code, the first alert box will display "one;" the second will display "two" and the third will display "three." Let us now see how we can call this arguments array from a nested function.
Here the content of the function has changed. When the function is called, the first statement in it calls the nested function. The inner function displays the arguments of the outer function. The outer function is what is called when you click the button. When the inner function is called by the outer function, it displays the arguments "one," "two" and "three" of the outer function. It uses the name of the outer function as you would use the name of an object. For example, the first array element is addressed as
ourFunction.arguments[0]
This addresses the arguments array of the outer function, and not the one of the inner function.
{mospagebreak title=ArgumentScope within Nested Functions – Proper}
Consider the following code segment, which is the modified form of the example I mentioned in the previous part:
function fnName1()
{
fnName2('I am argument 2');
alert(fnName2.arguments[0]);
function fnName2(param2)
{
function fnName3()
{
//nothing here
}
}
}
The outer-most function calls the middle function, passing the argument "I am argument 2." The next statement after this attempts to display the argument passed into the middle function. Now if you call the outermost function in your browser, nothing will happen, or you will see an error message in the task bar. If you replace the first two statements in the outer function with the following two, you will still have the same result.
fnName3('I am argument 3');
alert(fnName3.arguments[0]);
The truth is, independent of the level of the inner function, an outer function cannot use the argument of the inner function. Even though an outer function can call the immediate nested function, it cannot use the arguments or variables of the immediate nested function. We shall now look at the reverse case.
Consider the following code:
<html>
<head>
<script type="text/javascript">
function fnName1(param1)
{
fnName2();
function fnName2()
{
alert(fnName1.arguments[0]);
function fnName3()
{
//nothing here
}
}
}
</script>
</head>
<body>
<button type="button" onclick="fnName1('I am argument 1')">Call fnName1 Function</button>
</body>
</html>
When the button is clicked, the fnName1() function is called with the argument "I am argument 1" passed. The fnName1() function calls the middle function. The middle function displays the argument of the outermost function successfully.
Now consider the following code:
<html>
<head>
<script type="text/javascript">
function fnName1(param1)
{
fnName2();
function fnName2()
{
fnName3();
function fnName3()
{
alert(fnName1.arguments[0]);
}
}
}
</script>
</head>
<body>
<button type="button" onclick="fnName1('I am argument 1')">Call fnName1 Function</button>
</body>
</html>
Again, when the button is clicked, the fnName1() function is called with the argument "I am argument 1" passed. The fnName1() function calls the middle function. The middle function calls the innermost function. The innermost function displays the argument of the outermost function successfully.
Independent of the level of the outer function, the inner function can use the argument of the outer function.