12

在问我的问题之前,让我先声明一下。我知道做什么var,我知道块作用域,我知道变量提升。我不是在寻找有关这些主题的答案。

我只是想知道在函数中多次对同一个变量使用变量声明是否会产生功能、内存或性能成本。

这是一个例子:

function foo() {
  var i = 0;
  while (i++ < 10) {
    var j = i * i;
  }
}

前一个可以很容易地用j顶部声明的变量编写:

function foo() {
  var i = 0, j;
  while (i++ < 10) {
    j = i * i;
  }
}

我想知道这两种方法之间是否有任何实际区别。换句话说,var关键字除了建立范围之外还有什么作用吗?

我听说更喜欢第二种方法的原因:

  1. 第一种方法在实际上是函数作用域时给出了块作用域的外观。
  2. 变量声明被提升到范围的顶部,因此应该在此处定义它们。

我认为这些理由很好,但主要是风格上的。还有其他与功能、内存分配、性能等有关的原因吗?

4

5 回答 5

5

In JavaScript - The Good Parts Douglas Crockford 建议通过使用第二种方法并在其作用域的顶部声明变量,您将更容易避免作用域错误。

这些通常是由for循环引起的,并且非常难以追踪,因为不会引发错误。例如;

function() {
  for ( var i = 0; i < 10; i++ ) {
    // do something 10 times
    for ( var i = 0; i < 5; i++ ) {
      // do something 5 times
    }
  }
}

当变量被提升时,我们最终只有一个i。因此第二个循环覆盖了这个值,给了我们一个无限循环。

在处理函数提升时,你也会得到一些奇怪的结果。举个例子:

(function() {
  var condition = true;
  if(condition) {
    function f() { console.log('A'); };
  } else {
    function f() { console.log('B'); };
  }
  f(); // will print 'B'
})();

这是因为函数体被提升并且第二个函数覆盖了第一个函数。

因为搜索这样的错误很困难,而且不管任何性能问题(我很少关心几微秒),我总是在范围的顶部声明我的变量。

于 2013-03-26T21:36:15.127 回答
3

There will not be any differences during execution time. There might be a imperceptibly small difference in interpretation/compilation time, but that of course will be implementation dependent. There also might be a few bytes different in the size of the file, which could also affect download time. I don't think either of these are worth being bothered about.

As you already know, any variable declaration will be hoisted to the top of the function. The important thing to note is that this occurs during the interpretation/compilation process, not during execution.

Before a function is executed, the function must be parsed. After each function is parsed, they will both have all of the variable declarations moved to the top, which means that they will be identical and there will be no execution time cost incurred.

For the same reason, there are no memory cost differences. After parsing, there will be no differences at all.


Since you are not asking about style I am not telling you which I think is better. But I will say that the only reason you should prefer one over the other is style.

于 2013-03-26T21:23:15.950 回答
3

风格

主观的。我更喜欢var 靠近使用站点的方法,但我始终牢记范围规则。我也避免将多个声明组合成一个var,而是更喜欢多个var语句。

内存分配

变量不是对象:适用。由于提升规则,变量“slot”在所有情况下都具有相同的生命周期。

表现

不,在性能方面应该没有区别。虽然从技术上讲,一个实现可能真的把这搞砸了——但他们没有。

回答这个问题的唯一方法(除了查看细节中的每个实现)是使用 benchmark

结果:现代浏览器上的噪音差异

于 2013-03-26T21:33:27.703 回答
0

第二种方法将 4 个字符保存在 javascript 文件中 - 但就实际代码生成或执行速度而言,我认为根本没有任何区别。

于 2013-03-26T21:26:01.367 回答
0

您的示例将完全一样。不过,在块中使用“var”可能比您的示例更不清楚。例如,您想有条件地更新范围之外的变量(不使用“var”),或者改用本地“var”。即使该条件为假,“j”也会成为本地的。事实证明,它并不像看起来那样微不足道。

var j = 1;
function foo () {
    j = 2;
    if (false) {
        var j = 3; // makes `j = 2` local simply for being in the same function
    }
    console.log(j);
}
foo(); // outputs 2
console.log(j); // outputs 1

这是一个棘手的案例,仅通过查看代码可能无法按预期工作。

在顶部声明每个 'var' 没有缺点,只有优点。

于 2013-03-26T21:24:31.487 回答