1

I have the following code:

for (var i=0; i < 20; i++) {
    var itemButton = $('<button />').click(function(){ alert('Hello'); }).append('Hello');
    $('#container').append(itemButton);                            
}

Where i create lots of buttons each with a onclick function. Then i clear the #container using $('#shopSearchTopBar').empty(); and create the buttons again.

My question is: Is this a possible memory leak? Does Javascript frees the memory used for those anonymous functions i created the first time when i call the .empty() method on the #container or the memory gets freed an i can safely add those 20 new buttons each with his own new anonymous function?

5
  • I would use bind() instead of click(), qnd not the way you're presenting it. Commented Feb 2, 2011 at 20:55
  • 1
    @yoda: There's no functional difference between bind and click for assigning handlers. Commented Feb 2, 2011 at 20:57
  • @patrick dw: there is, check it : api.jquery.com/bind you can shorten your code with it's use. Also, I recommend live() if the markup changes frequently. Commented Feb 2, 2011 at 21:02
  • @yoda: I guess I don't know what you mean. A call to .click(fn) is just a wrapper for a call to .bind('click',fn), so I don't understand how the bind version shortens this code. There are other uses of bind where it can shorten a bit, but they don't really relate to the question. Commented Feb 2, 2011 at 21:10
  • @patrick dw: it was a sugestion. Commented Feb 2, 2011 at 21:11

2 Answers 2

4

Those functions are stored in jQuery.cache.

As long as you use jQuery methods like .empty(), that data will be cleaned up for all affected elements.

If you did something like this:

document.getElementById('container').innerHTML = '';

Then you'd likely have a pretty nasty memory leak because the connection between each element and jQuery.cache would be severed and that data (and likely more) would be sitting orphaned in the cache.

Stick to the jQuery methods when removing/overwriting content, and you'll be fine.

Even when doing this:

$('#container').html('');

...jQuery will clean up that data for affected elements.

Sign up to request clarification or add additional context in comments.

5 Comments

@patrick dw: html() doesn't clear the DOM, as far as I've tested.
@yoda: Yes it does. jsfiddle.net/cPRqw You need to pass the empty quotation marks as I did in my answer.
@patrick dw: That is the markup, not the DOM. Anyway, it's been a while since I crossed with that problem, don't know if it was solved meanwhile.
@yoda: jQuery only operates on the DOM. Markup comes from the server. You can add markup, but it is added using DOM methods/properties and then becomes part of the DOM. EDIT: Updated example.
@patrick dw: .. you win this round. If I find time latter to test it, I'll leave the feedback here. :)
0

If all the anonymous function does is show an alert, then I'd define the function outside the loop, and reference it by name. That way, it'll only get created once, instead of 20 times.

var clickHandler = function(){ alert('Hello'); };

for (var i=0; i < 20; i++) {
    var itemButton = $('<button />').click(clickHandler).append('Hello');
    $('#container').append(itemButton);                            
}

It's different if it makes use of closures, but that doesn't seem to be the case here.

4 Comments

I used just alert() to keep my example simple. Those functions do a lot more and also they make use of $(this) so i don't think i could use a function outside of the loop as you suggested.
Yes, you're right. I was focused more on the memory leak aspect. In terms of efficiency, you shouldn't construct identical functions in a loop. Creating a named function as you did allows you to share the single instance.
@daniels: It is ok to use it like that. this gets assigned when the function is called. Ultimately when you assign a handler to several elements like this $('.someElements').click(function(){}), jQuery is doing effectively the same thing, using a shared reference to the function among the different elements.
I just updated my code and used as suggested and works fine. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.