JavaScript にも、他のプログラミング言語と同様に、文字列や数値などのデータに名前を付けたり繰り返し利用するために、データを保持するための変数があります。
変数は、その変数を使用する前に宣言する必要があります。変数を宣言するキーワードとして、const、let、 var の3つがあります。
var はもっとも古くからある変数宣言のキーワードですが、意図しない動作を作りやすい問題が知られています。そのため ECMAScript 2015 で、var の問題を改善するために const と let という新しいキーワードが導入されました。
var example = '初期値OK';
example = '再代入OK';
var example = '再宣言OK';
let example = '初期値OK';
example = '再代入OK';
let example = '再宣言NG';
const example = '初期値OK';
example = '再代入NG';
const example = '再宣言NG';
varキーワードでは、値の再代入が可能な変数を宣言できます。
var bookTitle;
これは、bookTitle という名前の変数を宣言しています。この場合、bookTitle は値が代入されていないため、デフォルト値として underfined(未定義値) で初期化されています。ようするに「入れ物(変数)」は作ったけど、「中身(値)は空っぽ」って感じです。
この bookTitle という変数には、= 演算子を使うことで値を代入することができます。
var bookTitle;
bookTitle = "JavaScriptの本";
これで、bookTitle という変数に、「JavaScriptの本」という文字列を代入しました。
ここまでの、「変数の宣言 → 値の代入」までの流れを省略して、変数の宣言と同時に初期値を代入することができます。
var bookTitle = "JavaScriptの本";
これも、上の処理と同様に、bookTitle という変数に、「JavaScriptの本」という文字列を代入しています。
また、変数の宣言は、カンマ( , )で区切ることによって、複数の変数を定義することができます。
var bookTitle;
var bookCategory;
と、別々に宣言しても問題ありませんが、
var bookTitle, bookCategory;
と省略することができます。
もちろん、カンマ( , )で区切って省略した状態でも、初期値の代入をすることができます。
var bookTitle = "JavaScriptの本", bookCategory = "プログラミング";
これは次のように書いた場合と同じ意味になります。
var bookTitle = "JavaScriptの本";
var bookCategory = "プログラミング";
ここの例では、bookTitle という変数に、「JavaScriptの本」という文字列を代入し、bookCategory に「プログラミング」という文字列を代入しています。
var bookTitle = "JavaScriptの本",
bookCategory = "プログラミング";
カンマ( , )の後ろで改行をしておくと、後ほどの修正や、書き直したい場合などのメンテナンス時には見やすいかもしれません。けど、これだとわざわざカンマ( , )で区切った意味がなさそうにも見えます。処理状況に応じて、使い分ける必要がありそうです。
let キーワードでは、値の再代入が可能な変数を宣言できます。let の使い方は var とほとんど同じですが、再宣言だけは出来ません。
let bookTitle = "JavaScriptの本";
bookTitle = "新しいJavaScriptの本";
let で宣言した変数 bookTitle に「JavaScriptの本」を代入した後にもう一度、今度は「新しいJavaScriptの本」と違う文字列を代入しました。この"再代入"処理は問題ありません。
let bookTitle = "JavaScriptの本";
let bookTitle = "新しいJavaScriptの本";
let で宣言した変数 bookTitle に「JavaScriptの本」を代入した後に、今度は let で再宣言して「新しいJavaScriptの本」を代入しようとしましたが、こちらの"再宣言"は、エラーとなります。
エラーメッセージで、 SyntaxError: Cannot declare a let variable twice: 'bookTitle'. (構文エラー:let 変数を2回宣言出来ません:'bookTitle'。) と、表示されました。 ようするに「bookTitle を2回宣言しちゃダメですよー」と教えてくれました。
エラーが発生するということはプログラムの処理がここで止まって正常に動作しなくなりますのでご注意ください。
const キーワードも基本的な使い方は var や let と同じですが、値の再代入が出来ない変数を宣言します。また、これも let と同じように再宣言も出来ません。
const bookTitle = "JavaScriptの本";
var や let のキーワードでは再代入が可能なので、宣言だけを行った後に必要な値を別途代入しても問題ありませんでしたが、const キーワードは再代入ができないので、宣言と同時に値(初期値)を代入(定義)する必要があります。
宣言だけを行った場合はエラーになり、 SyntaxError: const declared variable 'bookTitle' must have an initializer. (構文エラー:const で宣言した変数 'bookTitle' には初期値が必要です) と、メッセージが表示されました。
let キーワードのところでも書きましたが、エラーが発生するということはプログラムの処理がここで止まって正常に動作しなくなりますのでご注意ください。
一般的に変数への再代入は「変数の値は最初に定義した値と常に同じである」という参照透過性と呼ばれるルールを壊すため、バグを発生させやすい要因として知られています。そのため、変数に対して値を再代入する必要がない場合は、const キーワードで変数宣言することを推奨しています。
変数に値を再代入したいケースとして、ループなどの反復処理の途中で特定の変数が参照する値を変化させたい場合があります。 そのような場合には、変数への再代入が可能な let キーワードを利用します。
var は let とよく似ていますが、var キーワードには同じ名前の変数を再定義できてしまう問題があります。
let や const では、同じ名前の変数を再定義しようとすると、構文エラー(SyntaxError)が発生します。 そのため、間違えて変数を二重に定義してしまうというミスを防ぐことができます。
一方、var は同じ名前の変数を再定義できます。これは意図せずに同じ変数名で定義してもエラーとならずに、値を上書きしてしまいます。
// "x" という変数を定義する
var x = 1;
// 同じ変数名の変数 "x" を定義できる
var x = 2;
// 変数 x は 2 となる
また var には変数の巻き上げと呼ばれる意図しない挙動があり、let や const ではこの問題が解消されています。そのため、現時点では「let は var を改善したバージョン」ということだけ覚えておくと良さそうです。
このように、var にはさまざまな問題があります。また、ほとんどすべてのケースで var は const か let に置き換えが可能です。そのため、これから書くコードに対して var を利用することは避けたほうが良さそうです。
どのキーワードにおいても宣言できる変数に利用できる名前のルールは同じです。また、このルールは変数の名前や関数の名前といった JavaScript の識別子において共通するルールとなります。
変数名の名前(識別子)には、次のルールがあります。
変数の名前は、半角のアルファベットである A から Z(大文字)と a から z(小文字)、_(アンダースコア)、$(ダラー)、数字の 0 から 9 を組み合わせた名前にします。JavaScript では、アルファベットの大文字と小文字は区別されます。
これらに加えて、ひらがなや一部の漢字なども変数名に利用できますが、全角の文字列が混在すると環境によって扱いにくいこともあるためお勧めしません。
const $ = "$";
// OK: $が利用できる
const _title = "_title";
// OK: _が利用できる
const jquery = "jquery";
// OK: 小文字のアルファベットが利用できる
const TITLE = "TITLE";
// OK: 大文字のアルファベットが利用できる
const es2015 = "es2015";
// OK: 数字は先頭以外なら利用できる
const 日本語の変数名 = "日本語の変数名";
// OK: 一部の漢字や日本語も利用できる
変数名に数字を含めることはできますが、変数名を数字から開始することはできません。これは変数名と数値が区別できなくなってしまうためです。
var 1st;
// NG: 数字から始まっている
var 123;
// NG: 数字のみで構成されている
また、予約語として定義されているキーワードは変数名には利用できません。予約語とは、var のように構文として意味を持つキーワードなどのことです。基本的には構文として利用される名前が予約されています。
var var;
// NG: 'var' は変数宣言のために予約されているので利用できない
var if;
// NG: 'if' は if 文のために予約されているので利用できない