Of course, you'd save yourself all of this trouble by using event
delegation[1]. :)

Best,

Tobie

[1] http://proto-scripty.wikidot.com/faq#delegation

On Nov 14, 2:04 pm, bluezehn <[EMAIL PROTECTED]> wrote:
> Yep cheers T.J. This all makes alot of sense. Nice to understand
> everything rather than just go about doing things in a certain way
> because it's the "done" thing!
>
> On Nov 14, 11:02 am, "T.J. Crowder" <[EMAIL PROTECTED]> wrote:
>
> > Hi,
>
> > > My tactic is going to be to stop defining them inline, therefore not
> > > causing a closure...
>
> > Yeah, I mean, it's not something you need to be paranoid about at all,
> > just something to keep in the back of your mind when you're dealing
> > with large numbers of things.  Small numbers of things are not a
> > problem, and of course use-and-forget closures (such as those
> > typically used with Enumerable.each) are not a problem because you
> > don't keep them.  And there are (lots of) times when a closure is
> > exactly what you want.  But something to keep in mind as part of the
> > larger picture of your code.
>
> > I should have mentioned that if you have this situation and the
> > closure is necessary (as they frequently are), you can minimize the
> > memory used by clearing any references that you no longer need.  So
> > with my doNiftyThing function earlier (again, a flawed example, but
> > there we are), if the closure is necessary and you're worried about
> > keeping the other things referenced, you could add this line at the
> > end:
>
> >     stuff = target = log = p = undefined;
>
> > The variables 'stuff', 'target', 'log', and 'p' are all still
> > referenced by the closure, but at least the things the *variables*
> > used to reference (the target element, the log element, the new
> > paragraph element, the 'stuff') are no longer referenced by those
> > variables, and so are eligible for cleanup if nothing else references
> > them.
>
> > -- T.J. :-)
>
> > On Nov 14, 10:28 am, bluezehn <[EMAIL PROTECTED]> wrote:
>
> > > Thanks T.J., very useful.
> > > I'm defining a lot of closures for my event handlers, ie, defining the
> > > functions for them inline (element.observe('click', function() { bla
> > > bla bla });), which are probably therefore using far too much memory.
> > > My tactic is going to be to stop defining them inline, therefore not
> > > causing a closure, and making sure that before I remove an element
> > > from the dom I'm no longer observing it.
>
> > > On Nov 14, 7:59 am, "T.J. Crowder" <[EMAIL PROTECTED]> wrote:
>
> > > > Hi,
>
> > > > > 1 ) But the problem is it's turned out to be a bit of a memory eater
> > > > > as there's quite a lot of methods on both classes.
>
> > > > That shouldn't be a problem if you're using Class.create, it assigns
> > > > the methods to the prototypes so the methods are shared across all
> > > > instances.  Are you trying to create private variables and then public
> > > > methods with access to them by creating methods within initialize?
> > > > E.g., are you doing this:http://pastie.org/314662
>
> > > > That kind of thing is sometimes recommended as a means of having true
> > > > private variables in JavaScript classes, and then having public
> > > > members that can access those private variables.  The problem with it
> > > > is that each *instance* of the class gets its own copy of the methods,
> > > > as well as the variables -- they're not shared on the prototype.  So
> > > > if you have 100 instances, each with 10 methods, you have 1,000
> > > > methods in memory.  (Which shouldn't be a problem if they're small,
> > > > but it could have been 10!)
>
> > > > > 2) If you remove an element from the DOM, are observers for that
> > > > > element also removed?
>
> > > > No, you'll want to call $('element').stopObserving() first -- with no
> > > > event name or handler, stopObserving unhooks all of the event handlers
> > > > for the element that were hooked up with observe()[1].  If you think
> > > > any of the element's children also have event handlers, you'll need to
> > > > unhook them as well.  Usually your application logic should give you
> > > > the information you need to do that in a targeted way, but if you need
> > > > to do it not knowing which children are hooked up, you can do
> > > > something like this:
>
> > > > function massUnhookAndRemove(element) {
> > > >     element = $(element);
> > > >     if (element) {
> > > >         // Unhook all children's handlers
> > > >         element.select('*').invoke('stopObserving');
>
> > > >         // Unhook element's handlers
> > > >         element.stopObserving();
>
> > > >         // Remove element
> > > >         element.remove();
> > > >     }
>
> > > > }
> > > > > 3) Does
> > > > > var bla = $('foo');
> > > > > // do some stuff with bla, leave it lying around on an object
>
> > > > Not if bla eventually goes out of scope so it's eligible for
> > > > reclamation.  But if you define any closures in that same scope, bla
> > > > will be kept alive becaues the closures have a reference to it.  E.g.:
>
> > > > function doNiftyThing(stuff) {
> > > >     var log;
> > > >     var p;
> > > >     var target;
>
> > > >     // Do it, and hook it up
> > > >     target = $('target');
> > > >     target.update(stuff);
> > > >     target.observe('click', function(evt) {
> > > >         // ...
> > > >     });
>
> > > >     // Log it
> > > >     log = $('log');
> > > >     p = new Element('p');
> > > >     p.update('Showed stuff');
> > > >     log.appendChild(p);
>
> > > > }
>
> > > > It may not look like it, but the closure being used as an event
> > > > handler on 'target' has live references to 'log' and 'p' (and
> > > > 'target', and 'stuff'), so the memory they point to will stay in use
> > > > as long as that closure exists.  Stupid example I supposed because of
> > > > course that logging stuff would be its own function, but you get the
> > > > idea.  Even if the closure doesn't seem to use something, it has
> > > > references to everything in scope where it's defined.  I've done an
> > > > article on closures that might help.[2]
>
> > > > > Constitute a memory leak? Or is that only when you also do:
> > > > > var bla = $('foo');
> > > > > $('foo').obj = bla;
>
> > > > JavaScript doesn't have a problem with circular references; the GC
> > > > will handle that gracefully (if nothing else references either object,
> > > > it'll clean them both up).  Internet Explorer has issues with circular
> > > > references involving non-JavaScript native objects, like DOM nodes --
> > > > it won't clean them up.  See Crockford's article on that.[3]
>
> > > > [1]http://prototypejs.org/api/event/stopObserving
> > > > [2]http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html
> > > > [3]http://javascript.crockford.com/memory/leak.html
>
> > > > HTH,
> > > > --
> > > > T.J. Crowder
> > > > tj / crowder software / com
>
> > > > On Nov 13, 11:22 pm, bluezehn <[EMAIL PROTECTED]> wrote:
>
> > > > > I've extensively used class.create for a calendar - each week has a
> > > > > class containing 7 days, also represented as objects of a class.
>
> > > > > 1 ) But the problem is it's turned out to be a bit of a memory eater
> > > > > as there's quite a lot of methods on both classes. Should architecture
> > > > > like this be a problem with memory?
>
> > > > > Regardless of the answer to the above question (which I really, really
> > > > > hope is no!), I'd also like to know the answer to some more
> > > > > questions...
>
> > > > > 2) If you remove an element from the DOM, are observers for that
> > > > > element also removed?
>
> > > > > 3) Does
> > > > > var bla = $('foo');
> > > > > // do some stuff with bla, leave it lying around on an object
>
> > > > > Constitute a memory leak? Or is that only when you also do:
> > > > > var bla = $('foo');
> > > > > $('foo').obj = bla;
>
> > > > > 4) What are other causes of common memory leaks in prototype usage?
>
> > > > > Thanks alot for any answers.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to