Reputation: 5839
I'm working with some code where I need to attach a series of events to dynamically created elements. I'm wondering if one way is better over the other with regards to memory leaks. I've spent hours with Chome's memory profile and I cannot for the life of me figure out how to use it so I can't tell if one way is creating a leak or not.
In both ways I detach the onclick
event before removing the nodes from the DOM but wasn't sure if there is something else I need to be aware of.
I've created an example below.
click me 1
creates a new div and assigns a named function to the first and second onclick
click me 2
creates a new div and assigns an anonymous inner function to the first and second onclick
function startIt1(div)
{
var newDiv = document.createElement("div");
newDiv.className = "two";
newDiv.innerText = "click me 1a";
newDiv.onclick = step1;
document.body.appendChild(newDiv);
}
function step1()
{
this.innerText = "click me 1b";
this.className = "three";
this.onclick = step2;
}
function step2()
{
this.onclick = null;
this.parentNode.removeChild(this);
}
function startIt2(div)
{
var newDiv = document.createElement("div");
newDiv.className = "two";
newDiv.innerText = "click me 2a";
newDiv.onclick = function()
{
newDiv.innerText = "click me 2b";
newDiv.className = "three";
newDiv.onclick = function()
{
newDiv.onclick = null;
newDiv.parentNode.removeChild(newDiv);
}
};
document.body.appendChild(newDiv);
}
div
{
padding: 20px;
margin: 20px;
}
.one
{
background-color: lime;
}
.two
{
background-color: yellow;
}
.three
{
background-color: cyan;
}
}
<div class="one" onclick="startIt1(this)">click me 1</div>
<div class="one" onclick="startIt2(this)">click me 2</div>
Upvotes: 0
Views: 69
Reputation: 1075219
Unless there's something that you haven't shown which is holding a reference to those event handlers, neither of the above retains memory unnecessarily after the handler has been removed.
The second one, using an inner function, theoretically keeps the context (which is an abstract object) of the call to startIt2
alive until the handler and element are removed, but only until then. That's because the inner function is a closure over that context. A smart JavaScript engine could optimize that a bit, but can't remove it entirely, because the inner function has a reference to newDiv
in it. (If you used this
instead, a smart engine would be able to optimize the context retention away entirely — whether it would depends on the engine and whether it's a hotspot in the code.)
Perhaps slightly tangental, but using named functions has benefits unrelated to memory consumption, such as meaningful names in call stacks and such... And of course, if you use the same handler in more than one place, you can use one function instead of more than one.
Upvotes: 3