JavaScriptで利用できる変数と定数について説明します。
C言語などを熟知されている方からすると、JavaScriptの変数はとてもラフな定義になっています。
別ページで説明したデータ型がまとめて扱われますので、整数とか浮動小数点とかを宣言する際には明示しません。
キーワードとしては以下の3種類があります。
具体的に見てみましょう。
宣言と初期化と代入について var キーワードを例にして見てみます。
《script》
var a = 1; var b, c; b = 2; c = 3; a = b + c;
この例の簡単な説明です。
上記は var キーワードで説明していますが、let キーワードでも同じです。
違うのは const キーワードで、こちらは定数としての扱いになるために、使い方としては宣言時に一緒に初期化を行い、その後の代入は行いません。
《script》
const a = 5;
ここで注意事項ですが、JavaScriptでは大文字と小文字が区別されますので、以下の2つの変数は別のものとして扱われます。
《script》
var a; var A;
var キーワードを例にして色々なデータ型を扱ってみましょう。
《script》
var a = 5; var b = 3.14; var c = "文字列の代入"; var d = false; var e = null; a = "整数から文字列に変更"; a = 1 / 3;
上から順番に整数、浮動小数点、文字列、論理値、null キーワードで初期化しています。
また a に整数に変わって文字列を代入しています。
さらに次の行では同じ a に計算式 1 / 3 を代入していて、この結果は0.33・・・の浮動小数点になります。
このように、変数の初期化後に別のデータ型に変更できるのも特徴の一つになります。
var キーワードだけでなく let キーワードでも同じことが出来ますが、const キーワードについては再代入しないのでデータ型が変わることもありません。
それでは var / let / const キーワードの違いを見て行きましょう。
定義をもう一度確認します。
const キーワードについては前述の通りで定数が基本ですので、再代入しない点が大きな違いです。
固定のテーブル類や文字列などを入れておくのに便利です。
《script》
const a = ["昨日", "今日", "明日", "明後日"];
上記は文字列を配列化して使う例ですが、これで所望の文字列が簡単に呼び出せるようになります。
同じ事は var キーワードや let キーワードでも出来ますが、const キーワードでは再代入しないという点を理解ください。
次にスコープの話になります。
スコープって何でしょうか、そのまま日本語にすると『範囲』ですね。
変数の及ぶ(使える)範囲といった理解でしょう。
しつこいようですが、var はローカル変数とグローバル変数を宣言、let と const はブロックスコープのローカル変数(定数)を宣言です。
まずは var キーワードから見てみましょう。
《script》
var a = 10; console.log(a, b); // a:10, b:undefined if (a == 10) { var b = 20; } console.log(a, b); // a:10, b:20 test(); function test() { var c = 30; console.log(a, b, c); // a:10, b:20, c:30 } console.log(a, b, c); // a:10, b:20, c:error
この例の簡単な説明です。
この時の a と b は関数の外でも中でも誰でも使えるグローバル変数、c は関数の中だけで使える ローカル変数であることが分かります。
同じことを let キーワードでやってみましょう。
《script》
let a = 10; console.log(a, b); // a:10, b:error if (a == 10) { let b = 20; } console.log(a, b); // a:10, b:error test(); function test() { let c = 30; console.log(a, b, c); // a:10, b:error, c:30 } console.log(a, b, c); // a:10, b:error, c:error
この例の簡単な説明です。
繰り返しになりますが、let キーワードはブロックスコープのローカル変数を宣言します。
a はグローバルな位置で宣言されているので、グローバル変数と同じ扱いになります。
b は if 文の中で宣言されているので、if 文の外ではアクセスできません。
これがブロックスコープの一番の特徴でしょう。
ブロックスコープは{ }の中だけで有効なスコープです。
c は関数の中だけで使える、ローカル変数と同じ扱いになります。
constもletと同じスコープになります。
前述の var キーワードの b に関する記載で、微妙に違和感があることお気づきでしょうか?
これが巻き上げという機能です。
具体的に見てみましょう。
《script》
console.log(B); // B:error B = 10; // error console.log(B); // B:error let B; console.log(B); // B:undefined B = 20; console.log(B); // B:20 console.log(b); // b:undefined b = 10; console.log(b); // b:10 var b; console.log(b); // b:undefined b = 20; console.log(b); // b:20
let キーワードと var キーワードで比較してみました。
let キーワードから説明します。
var キーワードの場合の違いは、b=10 を代入した時点でエラーが発生しない点です。
b の宣言はその下の行にあるので、宣言前にアクセスができる事になります。
このように宣言前にアクセスできることを『巻き上げ』と言います。
巻き上げが可能なのは var キーワードだけで、let キーワードや const キーワードは対象ではありません。
ただし、コードの読みやすさという観点では、変数へのアクセスは宣言後に行う事が好ましいと考えます。
同じ名前で変数を再宣言した時の挙動を var キーワードで確認します。
《script》
var a = 10; console.log(a); // a:10 test(); function test() { var a = 20; console.log(a); // a:20 } console.log(a); // a:10 if (a != 0) { var a = 30; } console.log(a); // a:30
この例では、関数 test() 内で再宣言された値は関数の外には出ませんが、if 文の中で再宣言された値は外でも有効です。
ブロックスコープではないという var の定義通りです。
ブロックスコープの let で同じことを試すと、関数に関しては外に出ないので同じですが、if 文で再宣言された値も外に出ません。
《script》
let = 10; console.log(a); // a:10 test(); function test() { let a = 20; console.log(a); // a:20 } console.log(a); // a:10 if (a != 0) { let a = 30; } console.log(a); // a:10
どう使い分けるかの定説はないと思いますが、参考として以下のようにまとめました。
途中で値を変更する予定がないものは、問題なく const キーワードを選択しましょう。
繰り返し使う数値や文字列は、const キーワードを選ぶべきす。
間違って値を書き換えようとしてもエラーになるので、分かり易いことはメリットです。
グローバルな変数を持ちたいなら、var キーワードが好ましいと考えます。
その変数がグローバルであることを明確に示すことに意味があるからです。
前述の通りで let キーワードでも同じことは出来ますので、必須ではないです。
逆にグローバルな変数と同じ変数名をブロックスコープに使ってしまった場合、var キーワードではグローバル変数側が書き変わってしまいますので、これを避けたいなら let キーワードを使う方が誤動作を避けられます。
ブロックスコープでのみ使う変数は、let キーワードが良さそうです。
理由は前述の通りで、同じ名前の変数に影響を与えない事です。
var キーワードと let キーワードのどちらを選ぶか、難しい問題ですが、チームでコード作成をするなら方針を共有して進めるのが良いでしょう。