473,396 Members | 1,933 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

(function() {...})(); explaination

I tested the JSON parse/to code from json.org and it works but I don't
understand how. Could someone explain how something in this format works:

(function() {...})();

Andrew Poulos
Jul 18 '06 #1
5 1373

Andrew Poulos wrote:
I tested the JSON parse/to code from json.org and it works but
I don't understand how. Could someone explain how something
in this format works:

(function() {...})();
function() {...}

- is an anonymous function expression (evaluated into a function object
when executed). The parentheses that surround it prevent it form being
interpreted as a function declaration (or a syntax error as a function
declaration needs a function name).

The final set of parentheses are a call operator and call the function
that was created by the evaluation of the function expression (with an
empty arguments list in this case).

Richard.

Jul 18 '06 #2
Richard Cornford wrote:
Andrew Poulos wrote:
>I tested the JSON parse/to code from json.org and it works but
I don't understand how. Could someone explain how something
in this format works:

(function() {...})();

function() {...}

- is an anonymous function expression (evaluated into a function object
when executed). The parentheses that surround it prevent it form being
interpreted as a function declaration (or a syntax error as a function
declaration needs a function name).

The final set of parentheses are a call operator and call the function
that was created by the evaluation of the function expression (with an
empty arguments list in this case).
That is a good explanation. The benefit of this form is that it allows the use
of new vars without making them global variables. It is always good to minimize
the use of global variables.

http://javascript.crockford.com/
Jul 18 '06 #3
Richard Cornford wrote:
Andrew Poulos wrote:
I tested the JSON parse/to code from json.org and it works but
I don't understand how. Could someone explain how something
in this format works:

(function() {...})();

function() {...}

- is an anonymous function expression (evaluated into a function object
when executed). The parentheses that surround it prevent it form being
interpreted as a function declaration (or a syntax error as a function
declaration needs a function name).

The final set of parentheses are a call operator and call the function
that was created by the evaluation of the function expression (with an
empty arguments list in this case).
Great explanation.

I'd never thought about it too much before, but when declaring objects
and methods this way:

var x = (function(){

// Declare a 'private' variable foo
var foo = 'foo';
return {

// 'privileged' function to modify the value of foo
setFoo : function(newFoo){
foo = newFoo;
},

// Function to show the value of foo
showFoo : function(){
alert(foo);
}
};
})();

A global variable 'x' is created with properties setFoo and showFoo
whose values are anonymous functions. It just occurred to me that the
use of 'foo' within the anonymous functions creates a closure back to
the 'outer' anonymous function - is that correct?

If no such closure is created (i.e. there are no references to
properties of the outer anonymous function) is it made available for
garbage collection once the call is finished? i.e. the net effect of:

var x = (function(){
return {
a : function(){},
b : function(){}
};
})();

is the same as:

var x = {};
x.a = function(){};
x.b = function(){};

and:

var x = { a : function(){}, b : function(){} };
--
Rob

Jul 18 '06 #4
RobG wrote:
I'd never thought about it too much before, but when declaring objects
and methods this way:

var x = (function(){

// Declare a 'private' variable foo
var foo = 'foo';
return {

// 'privileged' function to modify the value of foo
setFoo : function(newFoo){
foo = newFoo;
},

// Function to show the value of foo
showFoo : function(){
alert(foo);
}
};
})();

A global variable 'x' is created with properties setFoo and showFoo
whose values are anonymous functions. It just occurred to me that the
use of 'foo' within the anonymous functions creates a closure back to
the 'outer' anonymous function - is that correct?
Its an interesting question and I suspect the exact result depends on the
implementation. At the implementation level you have several objects which
could have their lifetimes affected: the anonymous function object, the
frame, and the variable 'foo'.

In Python the equivalent code would force foo to be stored in a cell
object, and both the outer and the inner functions would hold references to
the cell. The presence of a cell itself wouldn't extend the lifetime of
other variables in the outer function, nor would it prevent the function
itself being released once it was no longer referenced. [Python doesn't
allow assigning to the cell from the inner function, but that is just a
syntactic restriction: in the current implementation the Python bytecode
supports it.]

I don't believe any of the Javascript implementations provide any way to
track the lifetime of objects, so I think the only way to find out what it
actually does would be to inspect the source and that isn't always
possible. I would hope though that the implementation would be somewhat
similar to how Python does it.
>
If no such closure is created (i.e. there are no references to
properties of the outer anonymous function) is it made available for
garbage collection once the call is finished? i.e. the net effect of:

var x = (function(){
return {
a : function(){},
b : function(){}
};
})();

is the same as:

var x = {};
x.a = function(){};
x.b = function(){};

and:

var x = { a : function(){}, b : function(){} };
I would hope so, however in more complex cases where the code you want to
execute inside the function has local variables it is a useful technique to
avoid polluting the global object.
Jul 19 '06 #5
RobG wrote:
<snip>
var x = (function(){

// Declare a 'private' variable foo
var foo = 'foo';
return {

// 'privileged' function to modify the value of foo
setFoo : function(newFoo){
foo = newFoo;
},

// Function to show the value of foo
showFoo : function(){
alert(foo);
}
};
})();

A global variable 'x' is created with properties setFoo and
showFoo whose values are anonymous functions. It just
occurred to me that the use of 'foo' within the anonymous
functions creates a closure back to the 'outer' anonymous
function - is that correct?
Yes, the internal [[Scope]] propriety of the function objects resulting
from the evaluation of the two anonymous function expressions will
include all of the objects on the scope chain from the execution context
of the outer anonymous function, including its Activation/Variable
object.
If no such closure is created (i.e. there are no references
to properties of the outer anonymous function)
If there are no references to properties of the outer function's
execution context's Activation/Variable object then an implementation
may observe this and so not include that object on the inner function's
[[Scope]] chain, but the runtime overhead in making that observation
probably would not trade off well.
is it made available for garbage collection once the call
is finished?
I doubt it. The probability is that the Activation/Variable object will
not be garbage collected until after the function objects on who's
[[Scope]] chain it appears are themselves freed/garbage collected.
i.e. the net effect of:

var x = (function(){
return {
a : function(){},
b : function(){}
};
})();

is the same as:

var x = {};
x.a = function(){};
x.b = function(){};

and:

var x = { a : function(){}, b : function(){} };
Because there are no references to properties of the outer function's
Activation/Variable object in the first case the practical difference is
(near) zero, but I would still expected the Activation/Variable object
to be on the [[Scope]] chains of the inner function objects in the first
case. As a longer scope chain implies that Identifier resolution for
properties of the object at the end of the scope chain (the global
object) will take longer, it should be possible to determine whether
implementations do 'optimise' away the Activation/Variable object when
it is not actually being used, by timing Identifier resolution in the
situations above.

Richard.
Jul 19 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.