Hi,
> Closures is something that (can) cause memory leaks, right?
That's a complex topic. :-) Closures inherit, and therefore preserve
for their lifecycles, all of the local variables and parameters of the
functions they're defined in. If the closure is used immediately and
discarded, you don't much care. If you're going to retain a reference
to the closure (for instance, an event handler, or a dynamically-
created instance method), then you want to be aware of this. Here's
an example of the latter case:
function myNiftyMethod(param)
{
var v1, v2, v3;
// ... do something ...
// create and retain a closure to do something
this.thingy = function() {
// ... some code for the closure ...
};
}
When myNiftyMethod is executed, it creates a closure and remembers it
on the object instance as this.thingy. Since the closure holds a
reference to all of myNiftyMethods local variables and params (even
though it doesn't use them), and since the object instance keeps a
reference to the closure, 'param', 'v1', 'v2', and 'v3' all live on
for as long as the closure does. (Modulo cool JavaScript engine
optimisations, which I don't think are common yet and are harder for
the engine to do than it would at first seem.)
So closures can have memory *implications*; if you understand how they
work, though, and get used to some idioms around them, you won't cause
memory leaks (barring JavaScript engine bugs).
This is rambling a bit, but here's an example of the case where you're
using the closure immediately and discarding it:
function myNiftyMethod(someArray)
{
var v1, v2, v3;
// ... do something ...
// create and retain a closure to do something
someArray.each(function(item) {
item.doSomethingCool();
});
}
You don't keep a reference to the closure used in the each() method,
so you don't have to consider the implications of myNiftyMethod's
parameters and variables being retained. And it's a very powerful and
expressive way to deal with each item in the array.
> - I'm getting lost in how you constructed the onSuccess callback...
That's easy to do. :-) He's using a closure to construct and return
another closure; it's the inner one that gets assigned to the
onSuccess handler and retained, the outer one is run immediately and
discarded. If you look carefully at the code defining the onSuccess
handler, you'll see that the entire outer closure is wrapped in parens
-- the opening paren is right after "onSuccess:", and then right at
the end of the closure you see the closing paren followed by "(item)"
-- that "(item)" tells you he's *executing* the outer closure right
then, not just creating it. When it runs, the outer closure creates
the inner closure and returns it. *That's* what gets assigned to
onSuccess, the reference to the inner closure. The outer closure has
only the param it needs (item) and no local variables, so the inner
closure only preserves the information it really needs, not all of the
local variables where all of this is running.
Hope this helps,
--
T.J. Crowder
tj /crowder software / com
On Feb 23, 7:34 am, "Manu Temmerman-Uyttenbroeck"
<[EMAIL PROTECTED]> wrote:
> Hi,
>
> Closures is something that (can) cause memory leaks, right?
> kangax, would you mind explaining in a bit more detail why you wrote the
> code like you wrote it? I'm a bit lost in it. I restructured the code you
> wrote a bit...http://pastie.caboo.se/156248
> - Is there a reason why you don't write a ';' after the new Ajax.Request
> (...)?
> - Is there a reason why you don't write a ';' after the
> someArray.each(function(item)
> { ... })?
> - I'm getting lost in how you constructed the onSuccess callback...
>
> Thx...
>
> Manu.
>
> On Fri, Feb 22, 2008 at 11:11 PM, kangax <[EMAIL PROTECTED]> wrote:
>
> > Looks like a closure issue to me (solved with another closure).
> > Also, is that an array you are iterating over using "for..in" ?
>
> > siteListArray.each(function(item) {
> > var url = 'functions.php?command=numberOfErrors&site=' + item;
> > new Ajax.Request(url, {
> > onSuccess: (function(item) { return function(t) {
> > $('sidebar_site_div_' + item).update(t.responseText);
> > }})(item)
> > })
> > })
>
> > - kangax
>
> > On Feb 22, 4:02 pm, Chach <[EMAIL PROTECTED]> wrote:
> > > Hi everybody,
>
> > > I'm just getting kicked off on prototype and I'm having a problem that
> > > I'm hoping to get some help on.. I've had good success with
> > > Ajax.Updater, but now I'm trying to use Ajax.Request with the use of
> > > its callback abilities. My issue is that I'm trying to get a hold of
> > > one of the Element objects in the DOM using $('element'), however the
> > > name of the element can vary and so I have to assemble the name using
> > > the value in an array. It's almost like the siteListArray[x] does not
> > > work in the callback. Is it possible that the callback cannot see a
> > > variable that was declared earlier in my code at a global scope?
> > > Thanks in advance.
>
> > > for (x in siteListArray)
> > > {
> > > var url = 'functions.php?command=numberOfErrors&site=' +
> > > siteListArray[x];
> > > new Ajax.Request(url, {
> > > asynchronous:true,
> > > onComplete: function(transport) {
> > > $('sidebar_site_div_' +
> > > siteListArray[x]).update(transport.responseText);
> > > }
> > > });
>
> > > }
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby
on Rails: Spinoffs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---