3

The following program returns "local" and, according to the tutorial Im reading, it is designed to demonstrate the phenomenon ofclosure`

What I don`t understand is why, at the end, in order to call parentfunction, it assigns it to the variable "child" and then calls "child."

Why doesn`t it work by just writing parentFunction(); at the end?

var variable = "top-level";
function parentFunction() {
 var variable = "local";
 function childFunction() {
 print(variable);
 }
 return childFunction;
}
var child = parentFunction();
child();
asked Feb 22, 2011 at 4:51
1
  • Anything which is not an object property, is a closure. Commented Jan 22, 2013 at 16:08

3 Answers 3

6

parentFunction() returns another function which you assign to var child. Then, you call child() to invoke the function returned by the call to parentFunction().

Running just parentFunction(); at the end wouldn't do anything useful because you would just discard its return value which is a function. But this would work:

parentFunction()();

See this fiddle: http://jsfiddle.net/USCjn/

Update: A simpler example:

function outer() { // outer function returns a function
 return function() {
 alert('inner function called');
 }
}
x = outer(); // what is now in x? the inner function
// this is the same as saying:
// x = function() {
// alert('inner function called');
// }
x(); // now the inner function is called

See this fiddle: http://jsfiddle.net/bBqPY/

Functions in JavaScript can return functions (that can return functions (that can return functions ...)). If you have a function that returns another function then it means that when you call the outer function what you get is the inner function but it is not called yet. You have to call the value that you got as a function to actually run the body of the inner function. So:

x = f();

means - run a function f and store what it returns (which may be a string, a number, an object, an array, or a function) in x. But this:

x = f()();

means - run a function f, expect it to return a function and run that returned function as well (the second parentheses) and store in x what the returned function returned.

The function f here is a higher order function because it returns another function. Functions can also take another functions as arguments. One of the most powerful ideas of functional programming languages in general and JavaScript in particular is that functions are just normal values like arrays or numbers that can be returned and passed around.

You have to first grasp the idea of higher order functions to understand closures and the event system in JavaScript.

2016 Update

Note that currently this:

function outer() {
 return function() {
 alert('inner function called');
 }
}

can be written as:

let outer = () => () => alert('inner function called');

using the ES6 arrow function syntax.

answered Feb 22, 2011 at 4:55
Sign up to request clarification or add additional context in comments.

4 Comments

thank you. What initially invokes parentFunction() and why wouldn`t the same thing that initially invokes parentFunction() also not invoke childFunction, eliminating the need to have the inner function returned, assigned and called?
Why does running parentFunction() at the end discard the return value? Can you please explain why parentFunction()(); works?
@mjmitche Think that beetween the parentFunction invocation and the call of the result function you can have a lot of lines of code or you want to protect the closured variables... maybe a more useful function can shed some light. Try this link javascript.crockford.com/private.html
@Eineki, thank you. exactly which part of the code is the parentFunction invocation?
2

The amazing part about closures is that an inner function (in this case, childFunction) can refer to variables outside of its scope (in this case, variable). parentFunction doesn't return the result of childFunction, but an actual reference to the function!

This means that when you do the following...

var child = parentFunction();

...now, child has a reference to childFunction, and childFunction still has access to any variables it had when the function was created, even if they no longer exist.

In order to have parentFunction call childFunction, you'd need to change your code as follows:

From...

return childFunction;

To:

return childFunction();

Douglas Crockford (Pioneer of JSON, among other things) has a whole article devoted to closures, and scoping in javascript, and it would be well worth it to check out his other articles on javascript.

answered Feb 22, 2011 at 5:01

2 Comments

thank you, when you say that "parentFunction doesnt return the result of childFunction, but an actual reference to the function!", Im not exactly sure what "reference" means...is it some sort of Javascript command/function or does it just have its regular English meaning, in which case I don`t understand its usage here.
It's a bit complicated to descibe in so short a space, but basically I just mean that parentFunction returns the function childFunction. More specifically, it returns the exact same childFunction that was created inside parentFunction. It's kind of like a pointer in C++.
1

The point that is being demonstrated is that the function that was returned and assigned to child is still referencing the variable that was declared inside parentFunction instead of the one that was declared outside where child() is being invoked.

The only way to create a variable scope in javascript is in a function body. Normally the variable inside the parentFunction would have been discarded after the function returned.

But because you declared a function inside parentFunction that referenced variable in that scope and passed it out of parentFunction, the variable in the parentFunction is retained via the reference made in the new function.

This protects variable from outside manipulation except by functions that closed around it inside parentFunction.

answered Feb 22, 2011 at 5:09

4 Comments

Thank you. What do you mean when you use the word "reference" ... "is retained via the reference made in the new function." Is "reference" some sort of special javascript lingo/command, or is it simply a word with its regular English meaning?
@mjmitche: In the sense of referring to something that has your attention, but a bit more. It is in a sense retaining that variable or grabbing hold of it. To be accurate, in javascript, you can't actually reference a variable. Only its value. But I believe what's happening is the object that is (behind the scenes) responsible for the execution context of parentFunction is being retained and used by the new function when it executes so the reference to the inner variable remains valid. But you can think of the new function as holding variable to save it from garbage collection.
...I'll post a couple working examples here in a few minutes.
@mjmitche: Read through the comments in these examples. Basically, in the first example, each time we invoke parentFunction, the myVariable inside returns to its original value. But in the second example, we return a function from parentFunction, assign it to the child variable, and invoke child instead. You'll see that child continues to increment the original myVariable every time we invoke it. Hope this helps. (These examples use alert(). Sorry for the inconvenience.) ;o)

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.