Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #16137 > unrolled thread

Anonymous function in closure

Started byAndrew Poulos <ap_prog@hotmail.com>
First post2012-09-24 09:32 +1000
Last post2012-09-24 15:18 -0700
Articles 7 — 4 participants

Back to article view | Back to comp.lang.javascript


Contents

  Anonymous function in closure Andrew Poulos <ap_prog@hotmail.com> - 2012-09-24 09:32 +1000
    Re: Anonymous function in closure David Mark <dmark.cinsoft@gmail.com> - 2012-09-23 17:09 -0700
      Re: Anonymous function in closure Andrew Poulos <ap_prog@hotmail.com> - 2012-09-24 14:20 +1000
        Re: Anonymous function in closure David Mark <dmark.cinsoft@gmail.com> - 2012-09-24 00:10 -0700
        Re: Anonymous function in closure Gene Wirchenko <genew@ocis.net> - 2012-09-24 11:09 -0700
          Re: Anonymous function in closure Gene Wirchenko <genew@ocis.net> - 2012-09-24 13:27 -0700
    Re: Anonymous function in closure webnician@gmail.com - 2012-09-24 15:18 -0700

#16137 — Anonymous function in closure

FromAndrew Poulos <ap_prog@hotmail.com>
Date2012-09-24 09:32 +1000
SubjectAnonymous function in closure
Message-ID<8ZOdnd6tG7eeAcLNnZ2dnUVZ_vGdnZ2d@westnet.com.au>
If I have a closure like this:

function foo(a) {
   return function() {
     // do something with a
   };
}

var bar = foo(10);

document.getElementById('a').onclick = bar;


Why doesn't
   var bar = foo(10);
cause the anonymous function in 'foo' to be executed but clicking on 'a' 
does?

Andrew Poulos

[toc] | [next] | [standalone]


#16138

FromDavid Mark <dmark.cinsoft@gmail.com>
Date2012-09-23 17:09 -0700
Message-ID<4339e0e5-6f01-47ca-b83a-8626020e2e4b@r14g2000vbd.googlegroups.com>
In reply to#16137
On Sep 23, 7:32 pm, Andrew Poulos <ap_p...@hotmail.com> wrote:
> If I have a closure like this:
>
> function foo(a) {
>    return function() {
>      // do something with a
>    };
>
> }
>
> var bar = foo(10);
>
> document.getElementById('a').onclick = bar;
>
> Why doesn't
>    var bar = foo(10);
> cause the anonymous function in 'foo' to be executed but clicking on 'a'
> does?

Because the "foo" function just returns a reference to a function. It
doesn't call it. You set a property of a host object to reference that
function, causing it to be called on click events.

[toc] | [prev] | [next] | [standalone]


#16139

FromAndrew Poulos <ap_prog@hotmail.com>
Date2012-09-24 14:20 +1000
Message-ID<s_2dnb_oJNscQsLNnZ2dnUVZ_oidnZ2d@westnet.com.au>
In reply to#16138
On 24/09/2012 10:09 AM, David Mark wrote:
> On Sep 23, 7:32 pm, Andrew Poulos <ap_p...@hotmail.com> wrote:
>> If I have a closure like this:
>>
>> function foo(a) {
>>     return function() {
>>       // do something with a
>>     };
>>
>> }
>>
>> var bar = foo(10);
>>
>> document.getElementById('a').onclick = bar;
>>
>> Why doesn't
>>     var bar = foo(10);
>> cause the anonymous function in 'foo' to be executed but clicking on 'a'
>> does?
>
> Because the "foo" function just returns a reference to a function. It
> doesn't call it. You set a property of a host object to reference that
> function, causing it to be called on click events.

Ok, but what happens to the value, which in this case is 10, that is 
passed with the assignment to "bar"?

Andrew Poulos

[toc] | [prev] | [next] | [standalone]


#16140

FromDavid Mark <dmark.cinsoft@gmail.com>
Date2012-09-24 00:10 -0700
Message-ID<b943d598-a707-4ced-88ae-55fcf70a7530@a7g2000yqo.googlegroups.com>
In reply to#16139
On Sep 24, 12:20 am, Andrew Poulos <ap_p...@hotmail.com> wrote:
> On 24/09/2012 10:09 AM, David Mark wrote:
>
>
>
>
>
>
>
>
>
> > On Sep 23, 7:32 pm, Andrew Poulos <ap_p...@hotmail.com> wrote:
> >> If I have a closure like this:
>
> >> function foo(a) {
> >>     return function() {
> >>       // do something with a
> >>     };
>
> >> }
>
> >> var bar = foo(10);
>
> >> document.getElementById('a').onclick = bar;
>
> >> Why doesn't
> >>     var bar = foo(10);
> >> cause the anonymous function in 'foo' to be executed but clicking on 'a'
> >> does?
>
> > Because the "foo" function just returns a reference to a function. It
> > doesn't call it. You set a property of a host object to reference that
> > function, causing it to be called on click events.
>
> Ok, but what happens to the value, which in this case is 10, that is
> passed with the assignment to "bar"?
>

The "a" variable is bound in the closure created when you return the
function reference. From the code comment, I assume that's what you
want. It will be 10 until such time as code in the inner function
changes it.

[toc] | [prev] | [next] | [standalone]


#16142

FromGene Wirchenko <genew@ocis.net>
Date2012-09-24 11:09 -0700
Message-ID<o17168hf56bgum1ileldgkd14gva9032no@4ax.com>
In reply to#16139
On Mon, 24 Sep 2012 14:20:06 +1000, Andrew Poulos
<ap_prog@hotmail.com> wrote:

>On 24/09/2012 10:09 AM, David Mark wrote:
>> On Sep 23, 7:32 pm, Andrew Poulos <ap_p...@hotmail.com> wrote:
>>> If I have a closure like this:
>>>
>>> function foo(a) {
>>>     return function() {
>>>       // do something with a
>>>     };
>>>
>>> }
>>>
>>> var bar = foo(10);
>>>
>>> document.getElementById('a').onclick = bar;

     This mean that when a click occurs on the control a, call the
function referenced by the value on the right-hand side.

     No execution of the function occurs until a is clicked.

>>> Why doesn't
>>>     var bar = foo(10);
>>> cause the anonymous function in 'foo' to be executed but clicking on 'a'
>>> does?
>>
>> Because the "foo" function just returns a reference to a function. It
>> doesn't call it. You set a property of a host object to reference that
>> function, causing it to be called on click events.

     What he said.

     I have just fought through the jungle to understanding closures
myself.  I found this page to be very useful:
          http://www.javascriptkit.com/javatutors/closures.shtml
Work through the examples, and it will become much clearer.

>Ok, but what happens to the value, which in this case is 10, that is 
>passed with the assignment to "bar"?

     Nothing is done with it.  You did not specify anything.

     Well, not quite nothing.  It is part of the closure.  The value
is saved, but you are not doing anything with it that is being
executed yet.

     Take a look at this example:

***** Start of Included Code *****
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
  <title>2012-09-24: Another Closure</title>
</head>

<body>

<script type="text/javascript">

function Outer(a)
  {
  return function()
    {
	a*=2;
	return a;
	};
  }

var fInner=Outer(1);
alert("fInner ("+typeof(fInner)+")="+fInner);
alert(fInner());
alert(fInner());

</script>

</body>

</html>
***** End of Included Code *****

     Outer() defines a function that returns a function that does
something (doubles a and returns the doubling) and because this is a
closure, the value of a is saved.  The inner function is not executed
at this time.

var fInner=Outer(1);
     Set the saved value, and get a reference to the doubling
function.  The inner function is not executed at this time.

alert("fInner ("+typeof(fInner)+")="+fInner);
     What is that returned reference?

alert(fInner());
     Call the inner function updating the saved value and returning
that.  The output is 2.

alert(fInner());
     Call the inner function updating the saved value and returning
that.  The output is 4.  This shows that the updates to a are saved
between calls.

Sincerely,

Gene Wirchenko

[toc] | [prev] | [next] | [standalone]


#16144

FromGene Wirchenko <genew@ocis.net>
Date2012-09-24 13:27 -0700
Message-ID<87g168l697frh28psq5sjl4s29qc347uak@4ax.com>
In reply to#16142
On Mon, 24 Sep 2012 11:09:20 -0700, Gene Wirchenko <genew@ocis.net>
wrote:

     I am repeating my post and adding an addendum.

>On Mon, 24 Sep 2012 14:20:06 +1000, Andrew Poulos
><ap_prog@hotmail.com> wrote:
>
>>On 24/09/2012 10:09 AM, David Mark wrote:
>>> On Sep 23, 7:32 pm, Andrew Poulos <ap_p...@hotmail.com> wrote:
>>>> If I have a closure like this:
>>>>
>>>> function foo(a) {
>>>>     return function() {
>>>>       // do something with a
>>>>     };
>>>>
>>>> }
>>>>
>>>> var bar = foo(10);
>>>>
>>>> document.getElementById('a').onclick = bar;
>
>     This mean that when a click occurs on the control a, call the
>function referenced by the value on the right-hand side.
>
>     No execution of the function occurs until a is clicked.
>
>>>> Why doesn't
>>>>     var bar = foo(10);
>>>> cause the anonymous function in 'foo' to be executed but clicking on 'a'
>>>> does?
>>>
>>> Because the "foo" function just returns a reference to a function. It
>>> doesn't call it. You set a property of a host object to reference that
>>> function, causing it to be called on click events.
>
>     What he said.
>
>     I have just fought through the jungle to understanding closures
>myself.  I found this page to be very useful:
>          http://www.javascriptkit.com/javatutors/closures.shtml
>Work through the examples, and it will become much clearer.
>
>>Ok, but what happens to the value, which in this case is 10, that is 
>>passed with the assignment to "bar"?
>
>     Nothing is done with it.  You did not specify anything.
>
>     Well, not quite nothing.  It is part of the closure.  The value
>is saved, but you are not doing anything with it that is being
>executed yet.
>
>     Take a look at this example:
>
>***** Start of Included Code *****
><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
>"http://www.w3.org/TR/html4/strict.dtd">
><html>
>
><head>
>  <meta http-equiv="Content-Type" content="text/html;
>charset=iso-8859-1">
>  <title>2012-09-24: Another Closure</title>
></head>
>
><body>
>
><script type="text/javascript">
>
>function Outer(a)
>  {
>  return function()
>    {
>	a*=2;
>	return a;
>	};
>  }
>
>var fInner=Outer(1);
>alert("fInner ("+typeof(fInner)+")="+fInner);
>alert(fInner());
>alert(fInner());
>
></script>
>
></body>
>
></html>
>***** End of Included Code *****
>
>     Outer() defines a function that returns a function that does
>something (doubles a and returns the doubling) and because this is a
>closure, the value of a is saved.  The inner function is not executed
>at this time.
>
>var fInner=Outer(1);
>     Set the saved value, and get a reference to the doubling
>function.  The inner function is not executed at this time.
>
>alert("fInner ("+typeof(fInner)+")="+fInner);
>     What is that returned reference?
>
>alert(fInner());
>     Call the inner function updating the saved value and returning
>that.  The output is 2.
>
>alert(fInner());
>     Call the inner function updating the saved value and returning
>that.  The output is 4.  This shows that the updates to a are saved
>between calls.

     Addendum: Put a "()" after the definition of the inner function
so Outer is now:
function Outer(a)
  {
  return function()
    {
	a*=2;
	return a;
	}();
  }
and run it.  Outer() will instead return the execution of the inner
function and
          alert("fInner ("+typeof(fInner)+")="+fInner);
will output
          fInner (number)=2
The next alert() line will throw an error, because now, fInner is a
number instead of a function reference.

     Thank you for the opportunity to teach this.  It has helped
solidify my understanding of closures.

Sincerely,

Gene Wirchenko

[toc] | [prev] | [next] | [standalone]


#16145

Fromwebnician@gmail.com
Date2012-09-24 15:18 -0700
Message-ID<6e448087-cdec-4edd-ada8-21def1f2c0bf@googlegroups.com>
In reply to#16137
function foo(a) { 
   return function() { 
     // do something with a 
   }; 
} 

var bar = foo(10); 

- - - - - - - - - - - - - - -

The value of 'a' is not passed to the function 'bar', rather it becomes part of its environment, as if it was outside, in the global scope. The beauty of a closure is that you have a flexible way to 'construct' another function. The important trick is...
1) 'a' will persist for each call of bar() as if it was in the global scope
2) 'a' is not actually in the global scope to cause conflicts


A simple example...

function Plus(x) {
    return function (y) {
        return y + x;
    }
}

var plus8 = Plus(8);
var plus3 = Plus(3);

plus8(10); --> 18
plus8(3); --> 11
plus3(1); --> 4


- - - - - - - - - - - - - - -

A better example...

function Count() {
    var x = 0;
    return function() {
        x += 1;
        return x;
    }
}

var countA = Count();
var countB = Count();


countA(); --> 1
countA(); --> 2
countA(); --> 3
countB(); --> 1
countB(); --> 2
countA(); --> 4

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web