大型FOR循环中的新局部变量,是否有问题?

3
在这个简单的例子函数中:
doSomething = function(withThisId) {
  var videos      = getVideos(), // array of videos
      discovered  = false
  ;

  for(var i = 0; i < 50000; i++) {
    var keepToCheck = videos[i];

    if(keepToCheck.id == withThisId) {
      discovered = true;
      break;
    }
  }

  return discovered;
};

我想知道以下几点:
1. 在 for 循环中,我们每次迭代都会初始化一个名为 keepToCheck 的新变量,然后将其用于某些操作。这是否意味着每次都会创建一个新变量,因此可能存在 50,000 个 keepToCheck 变量存在于内存中(直到 GC 清除)?
或者 JS 引擎足够聪明,知道可以重复使用变量而不会创建重复项吗?
2. 如果我们在 for 循环外部初始化 var keepToCheck,然后只设置为 keepToCheck = videos[i];,是否有性能优势?
我一直在尝试研究这个问题,但在网络上找不到任何建议。
3个回答

1
在JavaScript中,只会创建一个变量。在第一次迭代后,keepToCheck已经存在并将被覆盖,而不是重新创建。
然而,出于组织目的,我更喜欢在需要时尽早列出所有变量。在这种情况下,我会有:
var videos = getVideos(),
    discovered = false,
    keepToCheck, i;

接着是代码的其余部分。如果某些变量仅在 if 内部使用,我会在该块中的第一件事就对它们进行 var


这是错误的,另一个变量被创建并将先前的变量发送到垃圾回收。 - AutoSponge

1

变量会被“提升”到它们所声明的函数的顶部,并在被覆盖时被垃圾回收(完全由VM /浏览器进行调度)。重复的var语句(例如,在循环中)只是浪费。虽然内存中不会有50k个变量,但它浪费处理时间并且根据垃圾回收运行的时间而消耗一些内存。这就是为什么最好在函数的顶部声明变量。尝试在此代码上运行JSLint / JShint以了解我的意思。


0

虽然我对JS不是很了解,但在其他具有垃圾回收机制的语言中,局部变量不会被垃圾回收 - 它们存在于堆栈上,因此在离开作用域后它们就消失了。因此,您不能同时拥有多个这些变量。但是,每次迭代可能会得到不同的地址。


JS的垃圾回收取决于浏览器,因此它可能在调用堆栈期间运行,也可能不运行。真的很难说。 - AutoSponge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接