Output Place

得た知識をアウトプットする場

varとconstとlet

javascriptにおいて
varとconstとletの違いはなんなのか。

constとletが新しくて、varはもう使わない。
constは定数。

とか、そんな感じでしか知らなかったので、少し調べてみました。

var,const,letの違いは、スコープと巻き上げ。らしい...

この違いを説明するのに、一旦はconstを置いといて、
varとletでの違いを書いていく。

1.スコープ

一言で違いをいうと、varは関数スコープでletはブロックスコープである。

varの場合
function callName(){
  var name = 'Taro';
  console.log(name); //Taro
  if (true) {
    var name = 'Jiro';
    console.log(name); //Jiro
  }
  console.log(name); //Jiro
}

これはvarを使った場合の例。
varは関数スコープなので、ifやforの中で変数を定義しても、スコープ範囲は関数内になるので、if文の外側にも反映されるようになっている。
if文の中であろうが外であろうが、関係なし。区別をつけない。

var name = 'Jiro'; をif文の中で定義しているが、if文の外で変数nameを出力してもそれが反映されていることがわかる。

一方のletは、、、
function callName(){
  let name = 'Taro';
  console.log(name); //Taro
  if (true) {
    let name = 'Jiro';
    console.log(name); //Jiro
  }
  console.log(name); //Taro
}

letはブロックスコープなので、ifやforの中で変数を定義すると、スコープ範囲はブロック内になるので、if文の中だけで反映されるようになっている。
if文の中と外で区別される。

let name = 'Jiro'; をif文の中で定義しているが、if文の外で変数nameを出力してもそれが反映されていないことがわかる。


以上が、varとletのスコープの違いでした。
個人的にはletの方が自然な感じがあります。(他の言語は知りませんがjavaはそうだったので)

2.変数の巻き上げ

変数の巻き上げとは、スコープ内で宣言した変数は、どこに書いてあろうと、スコープ内の一番はじめに定義されること。を意味する。

変数の巻き上げ自体はvarでもletでも起こるのだが、挙動が違うらしい。

varの場合
var name = 'Jiro';
function callName(){
  console.log(name); //undefind
  var name = 'Taro';
  console.log(name); //Taro
}

変数nameを関数callName()内の2行目で定義しているが、変数の巻き上げにより、スコープ内の先頭で定義されたことになる。
よって、グローバル変数のname='Jiro'は使われずに、スコープ内で定義された方を参照する動きになる。

つまりは、こう書いてるのと一緒ということ↓

var name = 'Jiro';
function callName(){
  var name; //スコープ内の先頭で定義されたことになっている。
  console.log(name); //undefind
  var name = 'Taro';
  console.log(name); //Taro
}

変数が初期化されていなかったら、出力結果はundefindになる。
これがvarの巻き上げの挙動。

一方のletは
let name = 'Jiro';
function callName(){
  console.log(name); //Uncaught ReferenceError: Cannot access 'name' before initialization
  let name = 'Taro';
  console.log(name); 
}

ちなみに、巻き上げが起こるのでこれと同じことになる↓

let name = 'Jiro';
function callName(){
  let name; //スコープ内の先頭で定義されたことになる。
  console.log(name); //Uncaught ReferenceError: Cannot access 'name' before initialization
  let name = 'Taro';
  console.log(name); 
}

letの場合はundefindではなく、エラーになってしまう。
letの場合、変数の巻き上げは起こっているのだが、変数が初期化されていないとエラーになってしまう。

これがletの巻き上げの挙動


以上がvarとletの大きな違いである。
個人的にはletの方が慣れた挙動をしていると感じた。

最後に、

letとconstの違い

簡単に言えば、letは再代入可。constは再代入不可。
constはconstantの略で、定数っていう意味。

ただ、constは要素の再代入は不可であるが、オブジェクト内の要素は変えることができる。

const name = 'Taro';
  let age = 20;
  const fruits = [
    {name: 'apple', price: 100},
    {name: 'orange', price: 80},
  ];
  name = 'Jiro'; //エラーが起きる
  age = 21; //可能
  fruits[0].price = 90; //オブジェクト内の要素の変更は可能

まとめ

以上が、var,let,constの違いでした。
できるだけ、letとconstを使っていきたいですが、varを使ってるコードもまだまだ存在するので、そこのコードの改修となると、
見極めていい感じに使い分ける必要がありそう。。。