0

Being new to JavaScript, I came across a feature in JavaScript where we can write function inside a function which looks cool, but I didn't understand any practical use of it and also how to call the child function?

var parent = "global";
function Parent() {
    alert(parent);

    function child() {
        alert("i am child");
    }
}

So, in the above example function parent embeds child function, but I'm not sure on the following 2 questions:

  1. What's the practical use of such syntax / functionality?

  2. How to call child function?

Dan D.
  • 73,243
  • 15
  • 104
  • 123
ismail baig
  • 861
  • 2
  • 11
  • 39
  • 2
    The two big reasons are: *access to closed-over variables* (i.e. closures) and *limiting scope/access*. In this case the `child` function is useless because it is never invoked. Any code that has *access* to the function-object can invoke it - however it obtains said function-object. (Remember, functions/function-objects in JavaScript are "just values".) – user2864740 Jan 30 '14 at 05:28
  • All local variables declared in parent() will be accessible to child() without the need to make them global or pass them as parameter. . – Mohammed Joraid Jan 30 '14 at 05:28
  • @Joraid: thanks for the reply, but how can i call child function. i mean what's the syntax. – ismail baig Jan 30 '14 at 05:30
  • @ismailbaig You can't with the provided code: the function is not invoked in the `Parent` function scope and the function-object is not exposed outside the scope. – user2864740 Jan 30 '14 at 05:31
  • you call if from inside the parent function, in that way it will be as a helper function within the parent() and only accessible from the parent. If you want to use from outside the parent, then declare the parent as an object using the keyword 'new' var par = new Parent(); and access the child thru the parent, not directly. e.g. par.child(); But then (reminded by user2864740) it should be used with the prototype or as an object attribute – Mohammed Joraid Jan 30 '14 at 05:31
  • @Joraid That won't work because `child` is not in the [prototype] and is not assigned to `this` in the "constructor" - it is quite simply never accessible outside the given `Parent` scope with the provided code. – user2864740 Jan 30 '14 at 05:33
  • 1
    Yes true, i was imagining the situation where he put the function as a class attribute child: function(){} – Mohammed Joraid Jan 30 '14 at 05:35
  • Personally, I use the child function to do the (html parsing or sub calculating/validation) while the parent to do the main task, eventual in the API you need to call one function to get the job done and have the element displayed to the user. – Mohammed Joraid Jan 30 '14 at 05:50
  • Btw, real time you mean Real Life example right? or this question has something to do with realtime processing! – Mohammed Joraid Jan 30 '14 at 05:52
  • @Joraid: i meant real life example, not realtime processing. – ismail baig Jan 30 '14 at 06:35

3 Answers3

1

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.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

This concept is mainly used in OOJS (Object Oriented JavaScript). Consider the example below:

var Employee=function(ename,eage){
var _name=ename;
var _age=eage;
this.getName=function(){return _name;};
this.getAge=function(){return _age;};
};

var e1=new Employee("Xyz",45);
var e2=new Employee("Abc",23);
e1.getName(); //output=Xyz
e1.getAge(); // output=45
and so on ...
kcak11
  • 832
  • 7
  • 19
0

It's a closure which is a way to control scope in JavaScript. Anything defined inside the closure is not visible outside the closure. With a small modification to your function you can call it like so:

var parent = "global";
        function Parent(a) {
        alert(parent);

        function child(b) {
            alert(a + b); //child can see both a and b
        }

        return child;
    }

    parent(1)(2);

This can be used to implement currying which is explained here Javascript curry - what are the practical applications?

Community
  • 1
  • 1
TGH
  • 38,769
  • 12
  • 102
  • 135