view core-javascript/closures.rst @ 213:0ea90a1819c2 default tip

Custom theming
author Radomir Dopieralski <radomir.dopieralski@allegro.pl>
date Wed, 27 Jun 2012 16:35:54 +0200
parents f9f6684f9b32
children
line wrap: on
line source

Closures
========

You'll see closures a lot in JavaScript.  The reasons for this are:

#. In JavaScript, :doc:`bind-is-transient`.

#. It is callback functions attached to DOM elements that respond to
   events.

#. Most code attaches callbacks to individual DOM elements (rather
   than delegating to a parent element).


Test code
---------

Here's the test code for closures.

.. literalinclude:: /core-javascript-work/tutorial.js
   :language: javascript
   :start-after: start closures
   :end-before: end closures


Discussion
----------

The factory function creates two functions, *get* and *set*, which
refer to the variable *value* of the factory function.  The *get*
function returns the value of this variable, while the *set* function
changes it.

To test the factory function we create two get-set pairs.  We then
test that each *set* operation changes the value return by its partner
*get* operation.

Finally, we test that the two pairs don't interfere with each other.


Explanation
-----------

Objects continue to exist so long as a reference remains to them.
When the last reference to an object is removed (or when the object is
part of *cyclic garbage*) the object can be destroyed.  When the
return value of a function is stored (say as the value of a variable)
then this return value continues to exist.  Similarly, anything
referred to by the return value continues to exist.

Closures come about when the return value of a function is itself a
function defined within the outer function (or contains references to
such functions).

Suppose the outer function returns an *inner function* (or in other
words a function that is defined within the outer function).  Suppose
also that the inner function uses a variable (or parameter) of the
outer function.  In this situation the inner function holds a
reference to the value of this variable.  The code in the inner
function can read (or get) this value.  It can also write to this
variable.

One final point.  Each call of the outer function creates a new
instantiation of the function variable.


Exercises
---------

A programmer, perhaps in a hurry, misses out a *var* in the example
above.  So now it reads:

.. code-block:: javascript

   var get_set_factory = function(){

      value;   // Here's the missing *var*.


#. Which tests to you expect to pass, and which to fail?

#. Make this change and run the tests.  Which actually fail?

#. Explain what is happening.

#. What does this tell us about coding and testing?