ES2015から新しく加わった変数let
とconst
。なんとなく新しいから使おう、良いものらしいから使おう、というのもアレなので、挙動の違いを体験してみる。
【目次】
- 変数var、let、constの違い
- varは再代入も再宣言もできる
- letは再代入はできるが再宣言はできない
- constは再代入も再宣言もできない
- 「再言言」「再代入」をエラーにすることで事故を防ぐ
- letとconstの使い分け
- まとめ
※参考:【HTML、CSS、JSの書式】これを読めばコードが読める!書ける!まとめ!(基本5+応用1記事) - クモのようにコツコツと
変数var、let、constの違い
一番大きな違いは再代入、再宣言です。
変数名 | 再代入 | 再宣言 |
---|---|---|
var | ○ | ○ |
let | ○ | × |
const | × | × |
(他に「巻き上げ」の挙動の違いもありますが、それはまた改めて…)
※参考:ES6時代の巻き上げ(hoisting) - Qiita
「再代入」「再宣言」とはなにか?具体例を見てみましょう。
varは再代入も再宣言もできる
まずはなんでもありのvar
から。慣れ親しんだ変数です。
年号は何?ボタンを押してみてください。
See the Pen hensu_01 by イイダリョウ (@i_ryo) on CodePen.
「昭和!」「平成!」「令和!」というアラートが立ち上がります。
もうすぐ新年号なので年号を値に入れてみました。コードを見ていきます。
//ボタン取得 const btn = document.querySelector(".btn"); //クリックイベント btn.addEventListener('click', function(){ //処理 }, false);
- 変数
btn
でHTML上の要素(class名.btn
)を取得 - 変数
btn
にクリックイベントを設定
クリックイベントの中に処理を書いていきます。中身はこちら。
//宣言 & 代入 var nengo = "昭和!"; alert(nengo); //再代入 nengo = "平成!"; alert(nengo); //再宣言 var nengo = "令和!"; alert(nengo);
var
で変数nengo
を宣言し、値に「昭和!」を代入。
アラートでnengo
を表示(昭和!)- 変数
nengo
に値「平成!」を再代入。
アラートでnengo
を表示(平成!) var
で変数nengo
を再宣言し、値に「令和!」を代入。
アラートでnengo
を表示(令和!)
一つ目は変数の宣言と代入を同時に行っています。普段よく書く書き方だと思います。
二つ目は変数の前にvar
がありません。これは変数の再代入です。値が上書きされます。
三つ目は再びvar
がつきます。これは変数の再宣言です。同じ名前の変数を宣言し、違う値を入れているのでこちらも値が上書きされます。
letは再代入はできるが再宣言はできない
次はlet。ボタンを押してみてください。
See the Pen hensu_02 by イイダリョウ (@i_ryo) on CodePen.
「昭和!」「平成!」「平成!」おや?令和が出ませんね…。コードはこちら。
//宣言 & 代入 let nengo = "昭和!"; alert(nengo); //再代入(OK) nengo = "平成!"; alert(nengo); //再宣言(エラー) //let nengo = "令和!"; alert(nengo);
let
で変数nengo
を宣言し、値に「昭和!」を代入。
アラートでnengo
を表示(昭和!)- 変数
nengo
に値「平成!」を再代入。
アラートでnengo
を表示(平成!) let
で変数nengo
を再宣言し、値に「令和!」を代入。
(エラーになるのでコメントアウトした)
アラートでnengo
を表示(平成!)
先ほどと同じ形ですが変数がvar
ではなくlet
です。この状態だとエラーになって処理(アラート)が実行されません。
原因は「再宣言」にあります。let
は同じ名前の変数を再宣言することができません。この再宣言をコメントアウトするとアラートが立ち上がります。
3個目のアラートは「再代入」の値を表示しているので「平成!」になるわけです。
constは再代入も再宣言もできない
最後はconst
。ボタンを押してください。
See the Pen hensu_03 by イイダリョウ (@i_ryo) on CodePen.
「昭和!」「昭和!」「昭和!」連呼していますね。。昭和への思いが強そうです。コードはこちら。
//宣言 & 代入 const nengo = "昭和!"; alert(nengo); //再代入(エラー) // nengo = "平成!"; alert(nengo); //再宣言(エラー) //const nengo = "令和!"; alert(nengo);
const
で変数nengo
を宣言し、値に「昭和!」を代入。
アラートでnengo
を表示(昭和!)- 変数
nengo
に値「平成!」を再代入。
(エラーになるのでコメントアウトした)
アラートでnengo
を表示(昭和!) const
で変数nengo
を再宣言し、値に「令和!」を代入。
(エラーになるのでコメントアウトした)
アラートでnengo
を表示(昭和!)
const
も元の形のままだとエラーで処理(アラート)が実行されません。
const
は「再代入」も「再宣言」もできないため、どちらもコメントアウトにするとアラートが動きます。
3つのアラートはすべて最初に宣言&代入した値を表示しているため昭和連呼になったわけです。
「再言言」「再代入」をエラーにすることで事故を防ぐ
なぜ「再言言」「再代入」でエラーになるのでしょう。エラーにするメリットは?
変数の値を変えることは普通はあまりありません。例えば円周率は(今は)3.14だし、消費税率は(今は)1.08です。
消費税を定義してくて変数zei
を宣言し1.08
を代入します。
//消費税 var zei = 1.08; //価格 var kakaku = 1000 //合計 var kei = (kakaku * zei) //1,080円
もし違う場所で全く同じ変数名で500
と宣言されたらどうなるでしょう。
//消費税 var zei = 1.08; //同名の別の変数 var zei = 500; //変数再宣言=値が上書きになる //価格 var kakaku = 1000 //合計 var kei = (kakaku * zei) //500,000円!!
こんな請求書されたら目ん玉飛びでちゃう!!
同名の別の変数zei
の再宣言によって最初のzei
の値が上書きしてしまったわけです。
こうした事故を防ぐ目的でlet
やconst
が生まれました。(他のプログラミング言語ではもともとあった概念)
letとconstの使い分け
「再言言」ができないlet
、「再代入」も「再宣言」もできないconst
。この二つはどう使い分ければいいでしょう。
基本的にはconst
でいいと思います。ただ、for文の条件の中の変数i
は再代入したいのでlet
にします。
例えばこれは従来の変数var
を使ったfor文です。
See the Pen hensu_04 by イイダリョウ (@i_ryo) on CodePen.
ボタンを押すと「昭和!」を5回連呼します。
for ( var i = 0; i < 5; i++ ) { alert("昭和!"); //昭和が5回 }
これをlet
にしても…
See the Pen hensu_05 by イイダリョウ (@i_ryo) on CodePen.
変数i
の数値が再代入されるので挙動は変わりません。
for ( let i = 0; i < 5; i++ ) { alert("昭和!"); //昭和が5回 }
これをconst
にすると…
See the Pen hensu_06 by イイダリョウ (@i_ryo) on CodePen.
変数i
の数字が再代入されないため、アラートが1回しか実行されません。
for ( const i = 0; i < 5; i++ ) { alert("昭和!"); //1回しか実行されない }
まとめ
コードが増えてくると変数の重複に気付きにくくなります。
var
のときは問答無用に値が上書きされていました。
エラーで処理が実行されず、ブラウザのデベロッパーツールを見るとエラーの場所がわかる。これで不測の事態が起こりにくくなります。
挙動の違いが体験できたので、私もこれからは変数にconst
やlet
を使っていきたく思います。それではまた!
※参考:ネイティブJSやってみたシリーズ
qiita.com