当我仍然可以访问它们时,javascript中的变量是GC吗?

时间:2011-10-10 18:13:27

标签: javascript

我在一个DOM元素中使用javascript创建一个属性,该函数也使用setInterval来回读这些值。

但是我发现从之前设置此属性的相同元素不再具有定义的值。这是相当奇特的,一种可能的解释是解释器认为不再存在对此属性的引用(即使赋予setInterval的匿名函数访问它)。

这很难解释所以我会在这里粘贴整个代码以及一些行号。

 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 < 0) alpha = 0;
 312             if (alpha > 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<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 > 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<elems.length;i++) {
 335                     var f_a = elems[i].fade_anim;
 336                     for (var j=0;j<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<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<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 > 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     }

这里发生的是我将一个元素数组传递给主函数createFadeEffect。此函数将为每个指定元素的.fade_anim属性创建并保存值。它附加到包含在其中的数组中。然后它使用匿名函数生成一个间隔,该函数检查每个元素中的.fade_anim。当调用createFadeEffect的多个调用,并且都指定相同的元素和相同的样式属性时,意图是元素的.fade_anim.arr累积指定的颜色值。在修改元素的适当样式时,间隔闭包循环遍历此数组以考虑所有颜色。

正在发生的是,对于某些元素,多次输入从第323行开始的块。我无法想出一种简单的方法来显示它们是什么特定元素,当它发生时,但我知道.def值被设置为中间值,这是过程的结果本身。这应该永远不会发生,因为无论何时设置值,我都不会自己删除它。

这是GC与我联系吗?我正在寻找有关如何更好地调试它以便跟踪.fade_anim s正在发生的事情的建议。

2 个答案:

答案 0 :(得分:0)

console.debug()是你的朋友(对于非IE)。

答案 1 :(得分:0)

我取得了一些进展。在355行,我需要做一个深层复制。当我只想修改一个临时变量时,我所做的就是使用存储的值。

另外......回应负面反馈。是的,我确实责怪系统行为不端,但可能不是。任何程序员都可以说他们从未这样做过吗?我想我应该重命名这个标题。