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;
  }
}

これら2つの方法の間に実際の違いがあるのだろうかと思います。言い換えれば、varキーワードはスコープを確立する以外のことをしますか?

2番目の方法を好むと聞いた理由:

  1. 最初のメソッドは、実際に関数スコープである場合にブロックスコープの外観を提供します。
  2. 変数宣言はスコープの一番上に持ち上げられるので、そこで定義する必要があります。

私はこれらの理由は良いと思いますが、主に文体的です。機能、メモリ割り当て、パフォーマンスなどに関係する他の理由はありますか?

4

5 に答える 5

5

JavaScriptの場合-GoodPartsDouglas Crockfordは、2番目の方法を使用し、スコープの上部で変数を宣言することで、スコープのバグをより簡単に回避できることを示唆しています。

これらはforループが原因であることが多く、エラーが発生しないため、追跡が非常に困難になる可能性があります。例えば;

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

変数を上げると、1つだけになりiます。したがって、2番目のループは値を上書きし、無限のループを提供します。

また、関数の巻き上げを処理するときに、いくつかの奇妙な結果を得ることができます。この例を見てください:

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

これは、関数本体が吊り上げられ、2番目の関数が最初の関数を上書きするためです。

このようなバグの検索は難しく、パフォーマンスの問題に関係なく(数マイクロ秒はほとんど気になりません)、常にスコープの先頭で変数を宣言します。

于 2013-03-26T21:36:15.127 に答える
3

実行時間に違いはありません。解釈/コンパイル時間には、知覚できないほど小さな違いがあるかもしれませんが、もちろんそれは実装に依存します。また、ファイルのサイズが数バイト異なる場合があり、これもダウンロード時間に影響を与える可能性があります。これらのどちらも気にする価値はないと思います。

すでにご存知のように、変数宣言は関数の先頭に持ち上げられます。注意すべき重要なことは、これは実行中ではなく、解釈/コンパイルプロセス中に発生するということです。

関数を実行する前に、関数を解析する必要があります。各関数が解析された後、両方の変数宣言が一番上に移動します。つまり、これらは同一であり、実行時間のコストは発生しません。

同じ理由で、メモリコストの違いはありません。解析後、違いはまったくありません。


あなたはスタイルについて質問していないので、私はどちらが良いと思うかをあなたに伝えていません。しかし、私はあなたが一方を他方よりも好むべきである唯一の理由はスタイルであると言います。

于 2013-03-26T21:23:15.950 に答える
3

スタイル

主観的var 私は使用サイトに近いアプローチを好みますが、常にスコーピングルールを念頭に置いています。また、複数の宣言を1つにまとめることは避け、複数のステートメントvarを優先します。var

メモリの割り当て

変数はオブジェクトではありません:適用されません。巻き上げ規則により、変数「スロット」の寿命はすべての場合で同じです。

パフォーマンス

いいえ。パフォーマンスに違いはありません。実装は技術的にこれを実際に台無しにする可能性がありますが、そうではありません。

これに答える唯一の方法は(細目ですべての実装を見る以外に)ベンチマークを使用することです。

結果:最新のブラウザでのノイズの違い

于 2013-03-26T21:33:27.703 に答える
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

これは、コードを見るだけでは期待どおりに機能しない可能性がある1つのトリッキーなケースです。

すべての「var」を上に宣言することにはマイナス面はなく、プラス面のみです。

于 2013-03-26T21:24:31.487 に答える
0

2番目の方法では、JavaScriptファイルに4文字を保存しますが、実際のコード生成または実行速度に関しては、まったく違いはないと思います。

于 2013-03-26T21:26:01.367 に答える