variables in javascript being GC'd when I can still access them?
<p>I am creating a property in a DOM element using javascript in a function which also uses <code>setInterval</code> to read back these values. </p>

<p>However I'm finding that the same elements which have had this property set from before, no longer have the value defined. This is rather peculiar and one possible explanation is that the interpreter thinks that no references to this property exist anymore (even though the anonymous function given to <code>setInterval</code> accesses it). </p>

<p>It is very difficult to explain so I will paste the entire code here along with some line numbers. </p>

<pre><code> 294     function toCamelCase(variable) {
 295         return variable.replace(/-([a-z])/g,function(str,letter){return letter.toUpperCase();});
 296     }
 297     function parseRGBStr(rgb) {
 298         return rgb.match(/rgba?\(([0-9]+),\s?([0-9]+),\s?([0-9]+)/).slice(-3);
 299     }
 300
 301     // the goal for this function is to create a self contained timer-driven
 302     // method for animating a fading color onto an arbitrary set of elements
 303     // and some particular style property belonging to them.
 304     // Furthermore, when multiple colors are to be set to the same property,
 305     // their colors are to be blended. Colors specified in a [r,g,b] format
 306     function createFadeEffect(elems, styleprop, colorBegin, duration) {
 307         var startTime = (new Date).getTime(); // start the effect immediately
 308         var endTime = startTime + duration;
 309         function lerpColors(colA, colB, alpha) {
 310             //alert("a: "+colA+" b: "+colB+' al: '+alpha);
 311             if (alpha &lt; 0) alpha = 0;
 312             if (alpha &gt; 1) alpha = 1;
 313             return [(1.0-alpha)*colA[0] + alpha*colB[0],
 314                     (1.0-alpha)*colA[1] + alpha*colB[1],
 315                     (1.0-alpha)*colA[2] + alpha*colB[2]];
 316         }
 317         var fade_anim_values = [startTime,endTime,colorBegin];
 318         for(var i=0;i&lt;elems.length;i++) {
 319             var f_a = elems[i].fade_anim;
 320             if (f_a == undefined) elems[i].fade_anim = {};
 321             f_a = elems[i].fade_anim;
 322
 323             if (f_a[styleprop] == undefined) {
 324                 f_a[styleprop] = {arr:[], def:parseRGBStr(document.defaultView.getComputedStyle(elems[i],'').getPropertyValue(styleprop     ))};
 325                 //buffer.push([startTime,elems[i],f_a[styleprop].def]);
 326             }
 327             f_a[styleprop].arr.push(fade_anim_values); // store reference rather than making copies
 328         }
 329         var handle = setInterval(function () {
 330             var nowTime = (new Date).getTime();
 331             if (nowTime &gt; endTime) {
 332                 // i'm expired. Clean myself up entirely from everything I've touched.
 333                 clearInterval(handle); // don't run me anymore
 334                 for (var i=0;i&lt;elems.length;i++) {
 335                     var f_a = elems[i].fade_anim;
 336                     for (var j=0;j&lt;f_a[styleprop].arr.length;j++) {
 337                         if (f_a[styleprop].arr[j] == fade_anim_values) { // that's me!
 338                             f_a[styleprop].arr.splice(j,1);
 339                             break;
 340                         }
 341                     }
 342                     if (f_a[styleprop].arr.length == 0) {
 343                         elems[i].style[toCamelCase(styleprop)] = '';
 344                     }
 345                 }
 346                 return;
 347             }
 348             for (var i=0;i&lt;elems.length;i++) {
 349                 var f_a = elems[i].fade_anim;
 350                 if (f_a[styleprop].arr.length == 0) { alert('encountered empty styleprop array in handler'); continue; } // nothing to      do here
 351                 // only require one interval-closure to process a particular element-styleprop combination.
 352                 if (f_a[styleprop].arr.length == 1 // i am the only interval attached to this element for this prop
 353                     || f_a[styleprop].arr[0] == fade_anim_values) // I am the zero-indexed handler
 354                 {
 355                     var colorValue = f_a[styleprop].def;
 356                     for (var j=0;j&lt;f_a[styleprop].arr.length;j++) {
 357                         var data = f_a[styleprop].arr[j];
 358                         var alpha = (nowTime - data[0]) / (data[1]-data[0]);
 359                         var f_c = lerpColors(data[2],f_a[styleprop].def,alpha);
 360                         colorValue[0] += f_c[0];
 361                         colorValue[1] += f_c[1];
 362                         colorValue[2] += f_c[2];
 363                     }
 364                     // clamp-norm
 365                     var max = Math.max(colorValue[0],colorValue[1],colorValue[2]);
 366                     if (max &gt; 255) {
 367                         colorValue[0] *= 1.0/max * 255;
 368                         colorValue[1] *= 1.0/max * 255;
 369                         colorValue[2] *= 1.0/max * 255;
 370                     }
 371                     var propstr = 'rgb('+Math.floor(colorValue[0])+','+Math.floor(colorValue[1])+','+Math.floor(colorValue[2])+')';
 372                     elems[i].style[toCamelCase(styleprop)] = propstr;
 373                 }
 374             }
 375         },30);
 376     }
</code></pre>

<p>What's going on here is that I pass an array of elements to the main function <code>createFadeEffect</code>. This function will create and save values to each specified element's <code>.fade_anim</code> property. It appends to an array contained within. Then it spawns an interval with an anonymous function, which checks <code>.fade_anim</code> in each element. When multiple calls to <code>createFadeEffect</code> are called, and both specify the same elements and the same style properties, the intention is for the element's <code>.fade_anim.arr</code> to accumulate the color values which are specified. The interval closures loop through this array to take all the colors into account when modifying the elements' appropriate styles. </p>

<p>What is happening is that the block starting at line 323 is entered multiple times for certain elements. I have been unable to come up with an easy way to display for me which particular elements they are, when it happens, but I do know that the <code>.def</code> value is being set to intermediate values which are a result of the process itself. This should never happen because whenever the value is set, I never delete it myself. </p>

<p>Is this the GC screwing with me? I am looking for suggestions for ways to debug it better to track what's going on with the <code>.fade_anim</code>s. </p>
