How to understand this form (something) (param);

J

john_woo

Hi,

I've read/used JavaScript for more that 2 years, but still don't
understand the following:

(function($) {
//when the DOM is ready...
window.addEvent('..,function() {

/* ALL JAVASCRIPT WILL BE IN HERE */

});
})(document.id);

Can any one tell:
1. any document explain this () () format;
2. what do the first and second () mean;
3. what does $ represent;
4. Does the inner statement like "window.addEvent..." work globally;
5. How to call its inner function from outside;
6. What's the advantage declare like this ()(), can this prevent
memory leak?
 
G

Gabriel Gilini

john_woo said:
Hi,

I've read/used JavaScript for more that 2 years, but still don't
understand the following:

(function($) {
//when the DOM is ready...
window.addEvent('..,function() {
This line throws a SyntaxError.
http://jibbering.com/faq/#posting read "Posting Code."
/* ALL JAVASCRIPT WILL BE IN HERE */

});
})(document.id);

Can any one tell:
1. any document explain this () () format;
This is a FunctionExpression. You can see its formal definition in the
language specification[1], and kangax has a nice article on named
function expressions which explains the differences from
FunctionDeclaration and FunctionExpression[2].
2. what do the first and second () mean;
The first pair of parenthesis acts as grouping operators, and is
optional. The second one contains the arguments that will be passed to
the expression.
3. what does $ represent;
`document.id', whatever that property contains.
4. Does the inner statement like "window.addEvent..." work globally;
It is executed in the same context which the program was before. So if
that expression is placed on the Global context, it will be executed in
the Global context[3].
5. How to call its inner function from outside; You can't.
6. What's the advantage declare like this ()(), can this prevent
memory leak?
No, it usually causes memory leaks by creating circular references[4].

[1]
http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf
[2] http://yura.thinkweb2.com/named-function-expressions/
[3] http://jibbering.com/faq/faq_notes/closures.html#clExCon
[4] http://jibbering.com/faq/faq_notes/closures.html

HTH
 
J

John_Woo

Gabriel said:
john_woo said:
Hi,
I've read/used JavaScript for more that 2 years, but still don't
understand the following:
 (function($) {
     //when the DOM is ready...
     window.addEvent('..,function() {
This line throws a SyntaxError.
http://jibbering.com/faq/#postingread "Posting Code."
        /* ALL JAVASCRIPT WILL BE IN HERE */
     });
 })(document.id);
[snip]
2. what do the first and second () mean;
The first pair of parenthesis acts as grouping operators, and is
optional. The second one contains the arguments that will be passed to
the expression.

All the parentheses are required for the example above:
     js> function(){}()
     typein:2: SyntaxError: syntax error:
     typein:2: function(){}()
     typein:2: .............^

But note that this does work:
     js> x = function(){}()
     js>

[snip]


Thanks lots Gabriel Gilini and Jonathan.

Further question is:

Do the following both get executed right away (the window property
changed)?
A. function(){ window.addEvent(...) } ()
B. var x = function(){ window.addEvent(...) } () ;

if yes, line A just a declaration, should not be executed; if no,
let's see the following example, in which jQuery.js is loaded along
with all codes:

(function($) {
jQuery.util = {
....
};

})(jQuery);

then the jQuery.util is called/used outside this function. This case
seems to change the jQuery property, and happed in a function
declaration stage.

I'm a bit stuck on this, Can any one clarify and make it clear?
 
G

Gabriel Gilini

Do the following both get executed right away (the window property
changed)?
A. function(){ window.addEvent(...) } ()
No. SyntaxError. Read kangax's reply.
B. var x = function(){ window.addEvent(...) } () ;
It does get executed, and `x' will have `undefined' stored in after it
exits.
if yes, line A just a declaration, should not be executed; And it isn't. I was mistaken.
let's see the following example, in which jQuery.js is loaded along
with all codes:

(function($) {
jQuery.util = {
...

};
})(jQuery);

then the jQuery.util is called/used outside this function. This case
seems to change the jQuery property, and happed in a function
declaration stage.
I can't understand your point here.
I'm a bit stuck on this, Can any one clarify and make it clear?
Where's the question?
 
J

Jorge

Gabriel said:
john_woo wrote:
Hi,
I've read/used JavaScript for more that 2 years, but still don't
understand the following:
 (function($) {
     //when the DOM is ready...
     window.addEvent('..,function() {
This line throws a SyntaxError.
http://jibbering.com/faq/#postingread"Posting Code."
        /* ALL JAVASCRIPT WILL BE IN HERE */
     });
 })(document.id);
2. what do the first and second () mean;
The first pair of parenthesis acts as grouping operators, and is
optional. The second one contains the arguments that will be passed to
the expression.
All the parentheses are required for the example above:
     js> function(){}()
     typein:2: SyntaxError: syntax error:
     typein:2: function(){}()
     typein:2: .............^
But note that this does work:
     js> x = function(){}()
     js>

Thanks lots Gabriel Gilini and Jonathan.

Further question is:

Do the following both get executed right away (the window property
changed)?
A. function(){ window.addEvent(...) } ()
B. var x = function(){ window.addEvent(...) } () ;

if yes, line A just a declaration, should not be executed; if no,
let's see the following example, in which jQuery.js is loaded along
with all codes:

(function($) {
jQuery.util = {
...

};
})(jQuery);

then the jQuery.util is called/used outside this function. This case
seems to change the jQuery property, and happed in a function
declaration stage.

I'm a bit stuck on this, Can any one clarify and make it clear?


identifierName (parameters)
^^PART1^^^^^^^ ^^^PART2^^^^

functionName(parameters) (parameters)
^^^^^^^^PART1^^^^^^^^^^^ ^^^PART2^^^^

(any expression) ( parameters )
^^^^^^ PART 1^^^ ^^^^PART 2 ^^^

(function optionalFunctionName (parameters) { ..body.. })
( parameters )
^^^^^^^^^^^^^^^^^^^^^^^ PART 1 ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^PART 2
^^^

PART 2 "(parameters)" is the call operator : () : whenever something
[1] that refers to a function is followed by a call operator, the
function that that something points to gets called.

[1] An expression's result or an identifier:

varPointingToaFunction(); : an identifier followed by a call operator.
(varPointingToaFunction)(); : expression whose result is a function
followed by a call operator.
(function(){})(); : expression (containing a function expression)
whose result is a function followed by a call operator.
varPointingToaFunction()(); : expression whose result is a function
followed by a call operator.
(varPointingToaFunction())(); : idem.
etc.
 
J

Jonathan Fine

Jorge said:
I'm a bit stuck on this, Can any one clarify and make it clear?


identifierName (parameters)
^^PART1^^^^^^^ ^^^PART2^^^^

functionName(parameters) (parameters)
^^^^^^^^PART1^^^^^^^^^^^ ^^^PART2^^^^

(any expression) ( parameters )
^^^^^^ PART 1^^^ ^^^^PART 2 ^^^

(function optionalFunctionName (parameters) { ..body.. })
( parameters )
^^^^^^^^^^^^^^^^^^^^^^^ PART 1 ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^PART 2
^^^

PART 2 "(parameters)" is the call operator : () : whenever something
[1] that refers to a function is followed by a call operator, the
function that that something points to gets called.

[1] An expression's result or an identifier:

varPointingToaFunction(); : an identifier followed by a call operator.
(varPointingToaFunction)(); : expression whose result is a function
followed by a call operator.
(function(){})(); : expression (containing a function expression)
whose result is a function followed by a call operator.
varPointingToaFunction()(); : expression whose result is a function
followed by a call operator.
(varPointingToaFunction())(); : idem.
etc.

There is an exceptional special case (the new operator):
Object

Same applies to your own constructors:
Object a=1

John (the OP), I hope this does not confuse you.

My advice is not to drop the parentheses, even though you are allowed to.
 
R

RobG

john_woo said:
I've read/used JavaScript for more that 2 years, but still don't
understand the following:
 (function($) {
     //when the DOM is ready...
     window.addEvent('..,function() {
        /* ALL JAVASCRIPT WILL BE IN HERE */
     });
 })(document.id);
[...]

Functions can be used to store code for reuse.  That's not what what's
happening in your example.  Instead, the function is being used to
create a closure.

The code pattern queried doesn't necessarily create any closures.

[...]
Let's now unpack (and change slightly) your example.

     var tmp = function(){
         var tgt = document.getElementById('ssss');

         // Lot's of code involving tgt.
     };

     tmp();
     tmp = undefined;

We've now got a variable 'tgt' that saves us some typing when writing
our code.  We can do other things with 'tgt', and this is the powerful
side of closures.

That code doesn't create any closures. It is equivalent to:

function tmp() {
/* same function body */
}

The only difference between the two is when the function is assigned
to the identifier tmp. In the first case, it's during execution of
global code - tmp will be undefined until the code is executed. In the
second, it will be assigned a value during variable instatiation and
have a value before any code is executed.

 But I don't think it's present in your example.

Yes, there is no closure.
The code I wrote can be condensed as:
     var tmp;  // Retained as worthless side-effect of above.
     (function(){ ....})();

There is a very big difference: in the first example, the function
expression is assigned to tmp so it can be reused. In the second, no
assignment is made so tmp stays undefined.

In this case there's no real difference between
     (function(){ var tgt = document.getElementById('sss'); ....})();
     (function(tgt){ ....})(document.getElementById('sss'));

I think the first form is clearer, although most people use the second.

There is no practical difference because using an identifier in a
formal parameter list is the same as declaring it locally. The second
form should only used if a value should be passed to tgt, otherwise,
it should be declared inside the function.

BTW, all the parentheses are required.
     js> function(){}()
     typein:2: SyntaxError: syntax error:
     typein:2: function(){}()
     typein:2: .............^

See Kangax's response for why.
 
J

Jorge

john_woo wrote:
 (function($) {
     //when the DOM is ready...
     window.addEvent('..,function() {
        /* ALL JAVASCRIPT WILL BE IN HERE */
     });
 })(document.id);
[...]

Functions can be used to store code for reuse.  That's not what what's
happening in your example.  Instead, the function is being used to
create a closure.

The code pattern queried doesn't necessarily create any closures.

Yes it does: the function(Expression) created and passed as a
parameter to window.addEvent captures the outer context(s) : read :
creates a closure. At least both document and $ are captured in that
closure, although as document might very well be the global document
it makes not much sense to talk about it being captured, but if it
weren't, it would be captured as well (and would be shadowing the
global document).
 
R

RobG

john_woo wrote:
 (function($) {
     //when the DOM is ready...
     window.addEvent('..,function() {
        /* ALL JAVASCRIPT WILL BE IN HERE */
     });
 })(document.id); [...]
Functions can be used to store code for reuse.  That's not what what's
happening in your example.  Instead, the function is being used to
create a closure.
The code pattern queried doesn't necessarily create any closures.

Yes it does: the function(Expression) created and passed as a
parameter to window.addEvent captures the outer context(s) : read :
creates a closure. At least both document and $ are captured in that
closure, although as document might very well be the global document
it makes not much sense to talk about it being captured, but if it
weren't, it would be captured as well (and would be shadowing the
global document).

I was discussing the general pattern, which doesn't *necessarily*
create a closure. The example does, but any function declaration or
expression inside another function will do that, it doesn't require
the specific pattern in the OP.
 
J

Jorge

I was discussing the general pattern, which doesn't *necessarily*
create a closure. The example does, but any function declaration or
expression inside another function will do that (...)

No no, not any:

this doesn't :
(function(){
function f () {};
})();

but this does:
(function(){
function f () {};
window.onload= f;
})();
 
J

Jorge

No no, not any:

this doesn't :
(function(){
  function f () {};

})();

but this does:
(function(){
  function f () {};
  window.onload= f;

})();

The same thing written in a slightly different way:

this doesn't :

(function () {
var f= function f () {};
})();

but this does:

(function () {
window.onload= function f () {};
})();
 
J

John G Harris

On Sat, 1 Aug 2009 at 20:16:45, in comp.lang.javascript, kangax wrote:

I'm actually curious which one of these examples can be considered to
be "forming a closure". I, for example, always thought (and it looks
like RobG thought so as well) that first example already does.

Perhaps, I'm just missing something here.

Case 1 :
function f(n)
{
return function() { alert(42); } ;
}
The returned function has nothing special about it. Describing what is
returned is straightforward.


Case 2 :
function f(n)
{
return function() { alert(n); } ;
}
The returned function has something very special about it. It displays a
parameter of f that ceased to exist when f finished executing.
Describing in detail what is returned is complicated and describing it
in simple words is almost impossible.

It seems to me that case 2 is an example of a closure, whereas case 1 is
not.

That said, the javascript implementation might include the closure
machinery in case 1 even though it's not used. On the other hand, it
need not.

John
 
J

Jorge

Case 1 :
  function f(n)
    {
      return function() { alert(42); } ;
    }
The returned function has nothing special about it. Describing what is
returned is straightforward.

Case 2 :
  function f(n)
    {
      return function() { alert(n); } ;
    }
The returned function has something very special about it. It displays a
parameter of f that ceased to exist when f finished executing.

Yep. Exactly. That's the important point: that f() exited and its
context should have been destroyed and garbage collected but instead
it isn't and survives in the closure.
 
J

Jorge

Yep. Exactly. That's the important point: that f() exited and its
context should have been destroyed and garbage collected but instead
it isn't and survives in the closure.

A context is what we used to call a stack frame, an old(1) Pascal
term. Other aspects of so-called "closures", such as access to the
outer (enclosing) function's ('free') vars are nothing new, we had
that in Pascal's nested subroutines back then (and it was *not* called
a "closure"). What is fresh, new, different in "closures" to what we
already had before is that the contexts can outlive (read: are not
destroyed immediatly after) the function call to which they belong, as
a consequence of (now first-class) functions being passed around as
data.

(1)http://en.wikipedia.org/wiki/Stack_frame#Structure
 
J

John G Harris

Yep. Exactly. That's the important point: that f() exited and its
context should have been destroyed and garbage collected but instead
it isn't and survives in the closure.

But earlier on, in a reply to RobG, you said that

(function(){
function f () {};
window.onload= f;
})();

creates a closure. It's the same as case 1 so now you're claiming it
doesn't create a closure.

What are you really trying to claim ?

John
 
J

Jorge

But earlier on, in a reply to RobG, you said that

(function(){
  function f () {};
  window.onload= f;

})();

creates a closure. It's the same as case 1 so now you're claiming it
doesn't create a closure.

(function g () {
window.onload= function f () {};
})();

1.- g() executes and exits.
2.- outside of g's context, window.onload holds a reference to f,
therefore f still exists even after g() has exited.
3.- as f's context includes g's context, neither g's (nor f's) context
can be destroyed/garbage collected.

(function g () {
var f= function f () {};
})();

1.- g() executes and exits.
2.- outside of g's context, nobody else holds a reference to f,
therefore,
3.- g's context and f's context can be and are normally destroyed/
garbage collected.
 
G

getify

On the topic of "closure" definition requiring something being made
available to the outside:

function foo() {
var x;
function bar(){alert(x);}
return {
a:function(){ bar(); }
}
}

In that example, certainly "a" has a closure to "bar".

But, the more interesting thing is that bar() has a closure, to "x".
Reason? Because it remembers the reference to "x", even if the outer
foo() has initially executed. But, it fails the strict definition that
bar() was made available to outside execution. It sort of is, but only
by indirect extension with another closure, not directly.

In my opinion, a function gets a closure if it CAN remember its
variable scope later, plain and simple. In practice you can't OBSERVE
or LEVERAGE an "internal" closure unless there's some sort of
execution chain directly or indirectly exposed, which of course much
itself be created via closure ("external").

"If a tree falls in the forest and noone hears it, did it make a
sound? Yes!"

Assigning an execution context ("external closure") to bar() certainly
is not what gives it the ability to remember "x" -- it must have had
that capability already by virtue of its declaration in the inner
function context. Without the external closure, you can't see the
internal closure, but nevertheless, it must exist because we know that
this function remembers "x" since it's able to work without throwing
symbol undefined errors.

So, to sum up, I think there's two closures happening. One internally,
and one externally.

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

Oh, and what about this, to even further reinforce (or perhaps
complicate):

function foo() {
var x;
function bar(myvar){
eval("alert("+myvar+");");
}
return {
a:function(myvar){ bar(myvar); }
}
}

(new foo()).a("x");

Which function(s) have a closure to "x"? I think both a() and bar().
Or maybe you could argue "neither", and that eval() just magically
creates the closure on the fly. Nevertheless, if a() wasn't present,
bar() would logically still be able to function, though we couldn't
practically demonstrate it.


--Kyle




No no, not any:
this doesn't :
(function(){
  function f () {};
})();
but this does:
(function(){
  function f () {};
  window.onload= f;
})();

That probably depends on exactly how you define a closure.

Any optimizations aside, when function is instantiated, it must
initialize (or at least behave as if it initializes) its internal
[[Scope]] property to contain the same objects as those in a scope chain
of current execution context (the one it's being instantiated within).
That [[Scope]] is then used to initialize function's execution context
(where it will be used entirely and only preceded with function's
Activation Object).

This means that in your first example -

(function(){
   function f(){};

})();

- when `f` is being instantiated, its [[Scope]] contains at least outer
function's Activation Object. Whether there are any variable/function
declarations performed in the outer function (so that Activation Object
has other properties but `arguments`) is technically irrelevant; it's
already closed over inner function and so will be used when initializing
inner function's execution context.

If we consider this process to be a closure, than we can say that even
in a simple (and pointless) case like this -

function f(){
   function g(){}

}

- a closure is being formed with inner function (over outer function).

On the other hand, we can make definition a bit stricter and say that
closure is formed only when there exist any free variables in any of the
activation objects (not counting implicit `arguments` property) captured
in function's [[Scope]], such as -

function f(){
   var x;
   function g(){}

}

We can also say that closure is formed only when inner function is being
made available to the outside of its containing function (which, I
think, is what you were trying to say), such as -

function f(){
   function g(){}
   return g;

}

Or we can have both prerequisites -

function f(){
   // free variable
   var x;
   // and function is made available for outside execution
   setTimeout(function(){
     return x;
   });

}

which would mean that both -

(function(){
   return function(){};

})();

// and

(function(){
   var x;
   (function(){})();

})();

- would be considered as those NOT forming the closure.

I was never really sure which one of these people mean when talking
about closures. For example, Richard's article - the most definite
description of closures to date - has a definition (coined by Lasse, I
think) which seems to "fit" first, least strict, case -

| A "closure" is an expression (typically a function) that can have free
| variables together with an environment that binds those variables
| (that "closes" the expression).

But then there's a more explicit explanation, and it already mentions
"outside availability" of inner function -

| A closure is formed when one of those inner functions is made
| accessible outside of the function in which it was contained, so that
| it may be executed after the outer function has returned.

I'm actually curious which one of these examples can be considered to be
"forming a closure". I, for example, always thought (and it looks like
RobG thought so as well) that first example already does.

Perhaps, I'm just missing something here.
 
J

Jorge

On the topic of "closure" definition requiring something being made
available to the outside:

function foo() {
var x;
function bar(){alert(x);}
return {
a:function(){ bar(); }
}

}

In that example, certainly "a" has a closure to "bar".

No. Both "a" and "bar" have access to foo's context. It's in foo's
context where x and bar are defined. It's in foo's context where they
are found and resolved.
But, the more interesting thing is that bar() has a closure, to "x".
Reason? Because it remembers the reference to "x", even if the outer
foo() has initially executed. But, it fails the strict definition that
bar() was made available to outside execution. It sort of is, but only
by indirect extension with another closure, not directly.

-That inner anonymous function referenced in the a: property of the
returned object is the reference that persists after foo()'s
execution,
-its context includes foo's context,
-function bar's context includes foo's context as well,
-bar is defined in foo's context as function bar () { alert(x); },
-x is defined in foo's context and has the value undefined
 
J

Jorge

(...)
An example I was puzzling about was this:

(function f () {
var x;
setTimeout(function g () {
alert(x);
}, 100);

})();

A reference to g persists after f returns: it's saved in the timer's
queue.
g's context includes (access to) f's context.
What's puzzling ?
:)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,091
Messages
2,570,605
Members
47,226
Latest member
uatas12

Latest Threads

Top