I'm not sure anyone actually gave you the simple answer for what you asked. Defining the child()
function inside the Parent()
function is just defining a "local" function whose scope is limited to only within the Parent()
function's code. It's analogous to a local variable that only exists inside a function.
So, when you have this:
function Parent() {
function child() {
alert("i am child");
}
}
You've created a new function named child
which can be called from the code inside of the Parent()
function like this:
function Parent() {
function child() {
alert("i am child");
}
child();
}
This function is truly local to within the Parent()
function and cannot be called from anywhere else. So, this will not work:
function Parent() {
function child() {
alert("i am child");
}
}
child(); // this function will be undefined
The simplest reason for defining a function this way is just to contain where it can be used and to reduce potential name conflicts. If you couldn't define local functions like this, then all functions would have to be global (or methods on some object) and you'd potentially have a giant set of possible name collisions. This way, you can define functions within a scope that they apply to and they don't potentially collide with any other functions defined similarly within their own scope.
When you get into more advanced uses of javascript, the child()
function also has access to all of the variables of its parent. So, you can do this:
function Parent() {
var msg = "Hello!";
function child() {
alert(msg);
}
child(); // will put up an alert that says "Hello!"
}
This allows those local functions to share all the variables from the parent context without having to pass them all to the function. This can be particularly useful when using callbacks because it allows the callbacks to have access to a whole context even though the callback was called by some other code. Here's a simple example of a callback having access to some useful state.
function blink(elem, numTimes, duration) {
var timer, visible = true;
// callback function that is called
function handleInterval() {
// toggle visible state
var val = visible ? "hidden" : "visible";
elem.style.visibility = val;
visible = !visible;
--numTimes;
if (numTimes <= 0) {
clearInterval(timer);
}
}
timer = setInterval(handleInterval, duration);
}
Here you notice that the handleInterval()
function has access to not only the local variables from the blink()
function, but also the arguments passed to it. This allows us to keep some state going for the setInterval()
without using global variables. There's also a more advanced thing going on here called a closure. Closure's can be a bit complicated of a concept, but understanding a couple uses is generally fairly simple.
In this case, the blink()
function gets called. It's job is to create an interval timer that, when called will toggle the visibility state of the passed in element. After a certain number of blinks, it will stop the interval timer. But, all the blink function does is call the setInterval()
function to schedule the interval timer. It then immediately finishes and is done executing. But, because the setInterval()
function has been schedule and it has been passed a reference to the handleInterval()
function and that function is in the scope of the blink()
function, then all the local variables of the blink()
function are "kept alive" and operating even though the blink()
function has already finished executing. In fact, these variables will be uniquely kept alive until the timer is stopped and nothing can call handleInterval()
any more. If javascript didn't have this capability, then a number of variables in this simple solution would have to be declared as global variables or properties of some object that persists for the duration of this activity. This technique allows the code to much cleaner and self-contained.
Local functions don't have to be named. They can also be anonymous. A more typical way to implement blink()
would be like this using an inline anonymous function callback instead of giving it a name:
function blink(elem, numTimes, duration) {
var timer, visible = true;
timer = setInterval(function() {
// toggle visible state
var val = visible ? "hidden" : "visible";
elem.style.visibility = val;
visible = !visible;
--numTimes;
if (numTimes <= 0) {
clearInterval(timer);
}
}, duration);
}
If you're only ever calling this function in one place, then it doesn't really need to be declared separately and given a name. It can, instead be defined inline like this as an anonymous function.