当サイトではアフィリエイトプログラムを利用しています

varとletの動作の違い基本

javascript

letで変数を宣言すると、反復サイクルごとに新しい変数を宣言。
各setTimeoutは異なる変数インスタンスを参照するため、最終的な出力は期待通りのカウントがされた数になる。

var変数には、ブロックレベルのスコープがない。
varを使用してforループで変数iを反復すると、すべてのsetTimeoutでiが同じ変数を指す。
なぜこうなるのか、というとsetTimeoutの実行タイミングによるもの。

実行されるのは通常のタスクキューの後。つまり、forループが終了した後に実行が開始。
変数にはループでカウントが増加された後の5が保存される。
結果、すべてのsetTimeoutコールバック関数は5を出力。


for (let j = 0; j < 5; j++) {

  setTimeout(() => {

    console.log(j);

  });

}

for (var i = 0; i < 5; i++) {

  setTimeout(() => {

    console.log(i);

  });

}

関数の場合も基本的に同じ。
var変数には、ブロックレベルのスコープがない。
変数iのスコープは、doCount関数のスコープ。

doCountへの各呼び出しはクロージャーと呼ばれるものを形成。
それぞれのクロージャーは独立しており、互いに干渉しない。
なので、
クロージャーはiの値を保存し、doCount()によって返される関数を呼び出すたびに、doCountの値が別々にカウントがされ増える。

letの場合も、もちろん互いに干渉しない。別々にカウントされる。


function doCount() {

  var i = 0;

  return function () {

    console.log(i++);

  };

}

var v1 = doCount();
var v2 = doCount();

v1();
v2();
v1();


function doCountL() {

  let i = 0;

  return function () {

    console.log(i++);

  };

}

let l1 = doCountL();
let l2 = doCountL();

l1();
l2();
l1();

今回の場合、返り値をvarで受けるかletで受けるかは影響しない。合わせてあるだけで。

現在、varを使うことはあまり推奨されていない。
基本的にはletか、今回は使っていないがconstを使うほうがいい。

PVアクセスランキング にほんブログ村
ブログランキング・にほんブログ村へ
タイトルとURLをコピーしました