1. ホーム
  2. javascript

[解決済み] let "と "var "の使い分けは?

2022-03-17 08:51:12

質問

ECMAScript 6導入 その let ステートメント .

と表現されるそうですね。 local 変数とどう違うのか、まだよく分かっていません。 var というキーワードがあります。

どのような違いがあるのでしょうか。どのような場合に let の代わりに var ?

解決方法は?

スコープルール

主な違いは、スコーピングルールです。で宣言された変数は var キーワードは直前の関数本体にスコープされる(そのため関数スコープとなる)のに対し let 変数は、その直前の 囲む で示されるブロック { } (となります(したがってブロックスコープ)。

function run() {
  var foo = "Foo";
  let bar = "Bar";

  console.log(foo, bar); // Foo Bar

  {
    var moo = "Mooo"
    let baz = "Bazz";
    console.log(moo, baz); // Mooo Bazz
  }

  console.log(moo); // Mooo
  console.log(baz); // ReferenceError
}

run();

その理由 let キーワードが導入されたのは、関数スコープが混乱し、JavaScriptのバグの主な原因の1つになっていたからです。

この例を見てください。 Stack Overflowの別の質問 :

var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
  // and store them in funcs
  funcs[i] = function() {
    // each should log its value.
    console.log("My value: " + i);
  };
}
for (var j = 0; j < 3; j++) {
  // and now let's run each one to see
  funcs[j]();
}

My value: 3 がコンソールに出力されるたびに funcs[j](); は、無名関数が同じ変数に束縛されていたため、呼び出されました。

ループから正しい値を取得するために、すぐに呼び出せる関数を作る必要がありましたが、これも毛嫌いされていました。

ホイスト

で宣言された変数が var キーワードは 吊り下げ (で初期化される)。 undefined これは、宣言される前でも、そのスコープでアクセス可能であることを意味します。

function run() {
  console.log(foo); // undefined
  var foo = "Foo";
  console.log(foo); // Foo
}

run();

let 変数は、その定義が評価されるまで初期化されません。初期化される前にアクセスすると ReferenceError . この変数は、ブロックの開始から初期化処理が行われるまで、"Temporal Dead Zone"にあると言われています。

function checkHoisting() {
  console.log(foo); // ReferenceError
  let foo = "Foo";
  console.log(foo); // Foo
}

checkHoisting();

グローバルオブジェクトプロパティの作成

トップレベルでは let とは異なり var は、グローバルオブジェクトにプロパティを作成しません。

var foo = "Foo";  // globally scoped
let bar = "Bar"; // not allowed to be globally scoped

console.log(window.foo); // Foo
console.log(window.bar); // undefined

再宣言

ストリクトモードの場合 var は同じ変数を同じスコープで再宣言できるのに対し let はSyntaxErrorを発生させます。

'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo1' is replaced with 'foo2'.

let bar = "bar1"; 
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared