web-dev-qa-db-ja.com

ES6で「var」キーワードを使用する理由はありますか?

Babelの ES6へのガイド は言う:

letは新しいvarです。

明らかに、唯一の違いは、varが現在の関数にスコープされるのに対し、letは現在のblockこの答え にいくつかの良い例があります。

ES6コードでvarを使用する理由がわかりません。関数全体に特定の変数のスコープを設定する場合でも、letで宣言を関数ブロックの先頭に配置することで、varでこれを行うことができます。また、forブロックなどでより細かくスコープを設定する場合は、それも可能です。

したがって、私の本能は、ES6コードを記述するときにvarの使用を完全に停止することです。

私の質問は、私はこれについて間違っていますか? varよりもletの方が望ましい正当なケースはありますか?

274
callum

Doug Crockfordはletについて this point で彼の講演「 The Better Parts 」について議論しています。

重要なのは、letは誤解の原因を回避することです、特に。ブロックスコープを持つ言語によって設定された期待を持つプログラマーのために。 varにはブロックスコープのようにのように見えますが、関数スコープ(関数全体で表示される変数を宣言します)があります。

varは、機械で生成されたコードのような極端な場合でも役立つ可能性がありますが、私は懸命にストレッチしています。

constも新しく、ブロックスコープがあります。let x = {'hi': 'SE'}以降はxに再割り当てできますが、const y = x以降はyに再割り当てできません。何かが誤ってあなたの下から変わってしまうのを防ぐので、多くの場合それが望ましいです。しかし、明確にするために、フリーズしない限り、オブジェクトy.hi = 'SO'を変更できます。)

実際には、ES6の印象は適切です:Adopt letおよびconstvarの使用を停止します。

"The Better Parts"の別のパフォーマンス では、修正するのではなく===が追加された理由 ==の問題==は「驚くべき」結果を生成するため、===を採用してください。)


明らかにする例

Mozilla Developer Network は、varが意図したとおりに機能しない例を示しています。これらの例は、Webページでonclickハンドラーを設定する現実的な例です。これは小さなテストケースです:

var a = [];
(function () {
   'use strict';
   for (let i = 0; i < 5; ++i) { // *** `let` works as expected ***
     a.Push( function() {return i;} );
   }
} ());
console.log(a.map( function(f) {return f();} ));
// prints [0, 1, 2, 3, 4]

// Start over, but change `let` to `var`.
// prints [5, 5, 5, 5, 5]

varは、すべてのループ反復が同じ関数スコープのi変数を共有するため、トリップします。ループが終了すると、値は5になります。


別のわかりやすい例

function f(x) {
    let y = 1;
    if (x > 0) {
        let y = 2;  // `let` declares a variable in this block
    }
    return y;
}
[f(1), f(-1)]  // --> [1, 1]

// Start over, but change `let` to `var`.
// --> [2, 1]

letは、ブロックスコープの変数を宣言します。 varは、関数全体で同じ変数を参照することで混乱させます。

219
Jerry101

正しいコードを記述している場合は、セマンティックを変更せずに、すべてのvarステートメントをletステートメントに変換できるでしょう。

letは、識別子が表示される範囲を縮小するため、推奨されます。これにより、初めて使用するサイトで変数を安全に宣言できます。

constletよりも望ましいです。参照を変更する必要がない限り、const宣言を使用します。これには、letのすべての利点に加えて、単一化された変数の存在を減らし、コードを一般的に推論しやすくします。参照を変更する必要があるかどうかわからない場合は、明示的に変更する必要があるまで、それをconstと宣言してください。

13
Aluan Haddad

私は必ずしもあなたが間違っているとは思いませんが、varの使用には注意事項があります。基本的に、letは、開発者がJavaScriptの愚かさ、特に名前の競合を回避するのに役立つはずです。 varはcloses関数のスコープに行きたいので、スコープが大きいようです。関数内のブロックのスコープ内で一時変数を使用できるようにする必要がある場合など、varが必要になる場合があります。そうでない場合は、varよりもletを優先すると、名前の競合が発生しやすくなります。簡単に言えば、ES6がletを導入した時期です。

5
curiousdork

Es6では「let」のみを使用することに同意する傾向があります。 AFIK、「let」を再宣言するとエラーが発生しますが(これは適切です)、「var」を使用すると、値をオーバーライドするだけです(es5の「strictモード」でも処理されます)。

2
yar1