はじめに
変数はJavaScriptの基本要素です。この記事では、変数とその宣言方法に焦点を当て、 let 、 const 、 var の使い方や、変数と密接に関わりのあるスコープという仕組みについて解説します。
JavaScriptに関する情報は書籍や記事として世の中にたくさんありますが、書かれた時代や執筆者の好みなどにより、変数の宣言方法に若干の違いがあります。小規模なコードの場合では違いが顕著に現れないこともありますが、プログラミングは微妙な選択が大きな影響を及ぼすことがあるため、正しい選択方法を身に付ける必要があります。
この記事を通じて、初学者の方がJavaScriptの変数を理解し、 let 、 const 、 var を適切にするための助けになればと思います。
この記事の対象者
- JavaScript初学者の方
- 変数の宣言方法について疑問がある方
- let、const、varの違いを具体的に学びたい方
この記事で学べること
- JavaScriptでの変数の基本
- let、const、varの違いと使用方法
- ブロックスコープについて
- 変数名の付け方
なぜ変数を使うのか
変数はプログラミングにおいてとても重要であり、多くのメリットがあります。変数を使うことにより、コードの可読性や保守性を向上させ、効率的なプログラムを作成できます。変数を使う主なメリットについて簡単に触れておきます。
データを再利用できる
データを変数に格納し、必要なときに再利用することができます。これにより、同じ値を繰り返し記述する必要がなくなり、コードが簡潔になります。
// 変数を使わない場合
document.getElementById('element').textContent = 'テキスト';
document.getElementById('element').style.color = 'red';
document.getElementById('element').style.backgroundColor = 'yellow';
// 変数を使う場合
const myElement = document.getElementById('element');
myElement.textContent = 'テキスト';
myElement.style.color = 'red';
myElement.style.backgroundColor = 'yellow';
コードの可読性の向上
適切に名前が付けられた変数はコードの可読性を向上させます。変数が何を表しているかが明確になっていると、他の開発者や未来の自分がコードを理解しやすくなります。
let height = 100;
let width = 100;
// 変数を使わない場合
console.log("エリアの面積:" + height * width);
// 変数を使う場合
let area = length * width;
console.log("エリアの面積:" + area);
変数の利用はコードを簡潔にする役割があります。変数を効果的に使うことで保守性が向上し、プログラムをより効率的に構築できるようになります。
JavaScriptでの変数の基本
JavaScriptの変数にはあらゆるデータを格納することができ、コードの中の多くの場所で利用することができます。変数は「 データを入れる箱 」と表現されることが多いです。
ここではJavaScriptにおいての変数の基本として、変数の宣言や代入、基本的なデータ型について解説します。
変数の宣言方法
変数を使用するには、最初にそれを宣言する必要があります。変数の宣言は、 let 、 const 、 var というキーワードを使用し、その後に変数名を記述します。 let 、 const 、 var には異なる挙動があり、後ほどこれらについて解説します。
変数の宣言は以下のように行います。
// キーワード 変数名;
let myVariable1;
var myVariable2;
上記のコードで宣言した変数は「 空っぽの箱 」です。 console.log() メソッドで確認すると「 undefined 」という、値が未定義であることを示す特別なデータが格納されています。
console.log(myVariable1); // 出力:undefined
console.log(myVariable2 ); // 出力:undefined
変数に値を格納するには「 =(代入演算子)」を使用します。
myVariable1 = 'myVariable1のデータ';
console.log(myVariable1); // 出力:myVariable1のデータ
変数の値は、その変数自身を呼び出すことができます。
let msg = 'Hello';
msg = msg + ' ' + 'World'; // 'Hello World'となります
変数の初期化
変数は宣言と同時に初期値を与えることができます。変数のデータは後で変更することができます。
let name = '三郎';
console.log(name); // 出力;三郎
name = '三四郎';
console.log(name); // 出力;三四郎
変数の宣言と同時に空の値を代入して変数の型を明示的にすることを「初期化」といいます。以下が例です。
let name = ''; // 文字列であることを明示的にする
let age = 0; // 数値であること明示的にする
基本的な変数の宣言方法は以上です。続いて、変数の型について解説します。
変数の型
JavaScriptは動的型付け言語であるため、変数の型は実行時に自動的に決定されます。これは、同じ変数が異なるデータ型の値を格納できることを意味します。この挙動を理解するために、まずは基本的なデータ型について簡単に触れておきます。
データ型とは
JavaScriptではさまざまなデータ型が定義されています。データ型とは、簡潔に述べるとデータの種類を示します。データの種類には文字列や数値などがあり、JavaScriptで取得したHTML要素にも特定のデータ型が定義されています。以下はJavaScriptの基本的なデータ型です。
- 文字列型(String):テキストデータを表現するための型で、シングルクォート「’」やダブルクォート「”」で囲われたデータは、数値やプログラムであろうと文字列型として扱われます。
- 数値型(Number):数値を表現するための型で、整数や浮動小数点数を格納できます。
- 真偽値型(Boolean):真(true)または偽(false)の値を表現し、条件式や論理演算に使用されます。
- 配列型(Array):複数の値を順序付けて格納するための型です。配列には異なるデータ型の値を格納できますが、扱いが複雑になるため、通常は統一された特性のデータを格納します。
- オブジェクト型(Object):複雑なデータ構造を表現するための型です。オブジェクトはキーとバリューのペア(プロパティ)を持ち、複数のデータをそれぞれに名前を付けて格納できます。
これらは基本的な型ですが、JavaScriptには他にも多くの型が存在します。これらの型の詳しい扱い方については以下の記事で解説しています。
JavaScriptの動的型付け
JavaScriptは動的型付け言語という特徴をもっており、変数の型はコードの実行時に自動的に決定されます。例として、前述の基本的なデータ型を定義する場合は以下のように行います。
let myString = '文字列です'; // 文字列型
let myNumber = 1; // 数値型
let myBoolean = true; // 真偽値型
let myArray = ['一郎', '二郎', '三郎']; // 配列型
let myObject = {name: '三四郎', age: 20}; // オブジェクト型
上記のように、JavaScriptにおいては「 代入された値の特徴 」によってデータ型が決まります。変数はデータ型が異なる場合でも再代入ができ、この特徴は変数を柔軟に扱うことができる一方、同じ変数が異なるデータ型の値を格納することができてしまうため注意が必要です。例えば、以下のようなコードでもエラーは発生しません。
let age = 20;
console.log(variable); // 出力:20(数値型)
age = '21';
console.log(variable); // 出力:21(文字列型)
また、数値型のデータを扱う場合は算術演算子(+、-、*、/など)を使用することがありますが、文字列型においても文字列の連結をする目的で「+」を使用することがあります。数値型のデータに対して文字列の連結が行われると、そのデータは数値型ではなく文字列型になります。
let a = 10;
let b = 5;
let c = '5';
console.log(a + b); // 出力:15(数値型)
console.log(a + c); // 出力:105(文字列型)
これらの挙動は、コードが大規模で複雑な場合にバグを発生させる要因になりえます。JavaScriptが動的型付け言語であるということに対する理解は、 let 、 const 、 var を適切に選択するためのヒントになります。
let、const、varの違いと使用方法
let 、 const 、 var キーワードには異なる挙動があり、どのような状況でどのキーワードを選択するべきかを理解することはとても重要です。これについて詳しく解説します。
letキーワードの特徴
let キーワードは、ブロックスコープを持つ変数を宣言します。ブロックスコープとは、特定のブロック内でのみ有効な変数を意味します。ブロックスコープは「 {} 」で表現されます。
{
let x = 10;
console.log(x); // 出力:10
}
console.log(x); // 「xが定義されていない」と怒られます
let を使用することで、変数のスコープをブロック内に制限することができ、意図しない変数の競合を避けることができます。
また、 let で宣言された変数は同じ名前を持つ変数を定義できません。
let x = 10;
let x = 20; // 「xはすでに宣言されている」と怒られます
let キーワードで宣言された変数は再代入が可能ですが、このように同じ名前を持つ変数を定義することができないことや、ブロックスコープを持つという特徴があります。スコープを意識することで安全に変数を扱うことができるため、再代入が必要な変数は一般的に let キーワードを使用します。
constキーワード
const キーワードで宣言された変数は、 let と同様にブロックスコープを持ちますが、値を再代入できないという特徴があります。これにより、 const キーワードで変数を定義する際は初期値を代入することが必須です。
const x; // 「初期値がありません」と怒られます
const y = 10;
y = 20; // 「const変数に代入が行われています」と怒られます
このような特徴により、 const キーワードで宣言した変数を「定数」と呼ぶことがあります。しかし、JavaScriptにおいては const で宣言された変数(定数)が必ず変化しないというわけではありません。例を挙げると、 const で宣言された変数が配列やオブジェクトの場合、内包する値の追加や削除、変更を行うことができます。
// 配列の場合
const x = [0, 1, 2];
x[0] = 1;
console.log(x); // 出力:[1, 1, 2]
// オブジェクトの場合
const y = {
name: '三郎',
age: 20
}
y.age = 30;
console.log(y); // 出力:{name: '三郎', age: 30}
この点については注意が必要ですが、このような挙動によりDOM操作を堅牢性を保ちつつ柔軟に行うことができます。よって、HTML要素を変数に代入する場合は値を変更する必要がない(変更されると保守が困難になる)ので const を使用することが多いです。
このように、 const は再代入できないという特徴により、 let よりもさらに安全に変数を扱うことができます。
varキーワード
var キーワードは、古いバージョンのJavaScriptで使用されていた宣言方法です。 var で宣言された変数は再代入が可能で、ブロックスコープを持たず、同じ名前の変数を定義することができます(できてしまいます)。
// ブロックスコープを持たない
{
var x = 0;
}
console.log(x); // 出力:0
// 同じ名前の変数名を定義できる
var x = 1;
console.log(x); // 出力:1
var x = 2;
console.log(x); // 出力:2
// 再代入が可能
x = 3;
console.log(x); // 出力:3
var で宣言された変数は、JavaScriptにおいてとても柔軟で危険な変数です。古いブラウザや古いJavaScriptが使用されたプロジェクトに対応する目的で var が使用されることはあるかも知れませんが、新しくJavaScriptで開発を行う場合は var キーワードの使用は避けるべきです。
JavaScriptでプログラミングを行う際はスコープの意識がとても重要なので、スコープを持つletやconstを使って変数を宣言するようにしましょう。
スコープについて
let や const で宣言した変数を適切に利用するには、スコープについての基本的な理解をする必要があります。スコープは、変数がどの範囲でアクセス可能かを決定する概念です。スコープについて理解することは、なるべく安全に変数を扱うための助けになります。
スコープの種類
JavaScriptには主に二つのスコープがあります。
- グローバルスコープ:グローバルスコープはプログラム全体で有効なスコープです。グローバルスコープ内で宣言された変数は、どこからでもアクセスすることができます。
- ローカルスコープ:ローカルスコープは関数および{}ブロック内で有効なスコープです。それぞれを「関数スコープ」や「ブロックスコープ」という場合もあります。
例を挙げると、以下のような感じです。
let x = 10; // グローバルスコープ
{
let x = 20; // ブロックスコープ
}
function myFunction() {
let x = 30; // 関数スコープ
}
ブロックスコープにより、グローバルスコープの x 変数とブロックスコープ内の x 変数は違うものとして扱われます。つまり、 let や const キーワードを使用した場合でも同じ名前の変数を定義でき、グローバルスコープの変数が書き換えられることもありません。
let x = 10;
{
let x = 20;
console.log(x) // 出力:20
}
console.log(); // 出力:10
グローバルスコープはどこからでもアクセスできるため便利に思うかもしれませんが、違うJavaScriptファイルからでもアクセスできてしまいます。複数のJavaScriptファイルを読み込んでいる場合は予期せぬ変数の書き換えが行われる可能性があるため、グローバルスコープは推奨されません。
意図しない変数の書き換えが行われないよう、できるだけローカルスコープを利用することが推奨されます。
スコープチェーンについて
ローカルスコープは入れ子構造になることがよくあります。JavaScriptでは、スコープチェーンという仕組みにより内側のスコープから外側のスコープの変数にアクセスできます。
スコープチェーンは以下のように動作します。
- 変数を呼び出した場所と同じスコープ内で変数を探します。
- もし同じスコープ内に見つからなければ、外側のスコープを探します。
- 2のプロセスを続け、変数が見つかれば検索を終了します。
スコープチェーンは最終的にグローバルスコープまで遡ります。以下は、スコープチェーンの動作を確認するための簡単な例です。
let x = 10;
{
let x = 20;
{
console.log(x); // 出力:20
}
}
{
{
console.log(x); // 出力:10
}
}
スコープチェーンは関数でも同様に作用します。
let x = 10;
function myFunction1() {
let x = 20;
function myFunction2() {
console.log(x);
}
myFunction2();
}
myFunction1(); // 出力:20
スコープの解説のところで「 ブロックスコープで宣言した x 変数はグローバルスコープで宣言した x 変数と違うものとして扱われる 」という説明をしましたが、ブロックスコープが入れ子構造になっている場合でも同じです。スコープチェーンの理解は、変数がどの値を参照するかを理解するための助けになります。
変数名の付け方やポイント
変数名はコードの可読性や保守性に大きな影響を与え、適切な変数名を選ぶことでコードを理解しやすくすることができます。命名規則はチームやプロジェクトによって異なりますが、ここでは、JavaScriptにおいての一般的な変数名の付け方やポイントについて解説します。
記述方法の一貫性
変数名は一貫性のある記述方法で命名することが重要です。JavaScriptでは一般的に「キャメルケース」という記法が推奨されています。キャメルケースは、変数や関数、メソッドなどの識別子を書く際に単語の先頭を小文字で始め、次にくる単語の先頭を大文字で始めるスタイルです。例えば、「myVariable」や「calculateTotalAmount」などがキャメルケースの例です。
「スネークケース」という記法も稀に使われることがあります。スネークケースは単語をアンダースコアで繋ぐスタイルです。例えば、「my_variable」などがスネークケースの例です。スネークケースはJavaScriptではあまり一般的ではありませんが、他のプログラミング言語やプロジェクト内のコーディング規約に従っている場合に見られることがあり、他の言語との統合や既存のコードベースへの適用など、特定の状況で使用されることがあります。
let myVariable = 'キャメルケースです';
let my_variable = 'スネークケースです';
予約語を回避する
JavaScriptには予約語というものが存在します。例えば、この記事で解説した let や const 、 var など、JavaScriptで特別な意味を持つ単語です。予約語を変数名として使用すると、エラーや意図しないバグが発生する可能性があります。
以下はJavaScriptの予約語の一覧です。
break
case
catch
class
const
continue
debugger
default
delete
do
else
export
extends
false
finally
for
function
if
import
in
instanceof
let
new
null
return
static
super
switch
this
throw
true
try
typeof
var
void
while
with
yield
初学者の方が予約語を全て覚える必要はありません。変数名を複数の単語で付けることで予約語との衝突を防ぐことができます。
複数の単語を使う
変数名に複数の単語を使用することは、変数の意味を具体的に示す役割を果たします。意味のある単語を複数使用することで、コードの可読性が向上します。
let name; // 何の名前か曖昧
let customerName; // 顧客名だとわかる
長い変数名はかえって読みにくくなる可能性があるので、省略しても意味の通じやすい単語は省略されることがあります。
let primaryButton;
let primaryBtn; // ButtonをBtnと省略
以下は、一般的に省略しても意味の通じやすい単語の例です。
- temp:temporary(一時的な)
- max:maximum(最大)
- min:minimum(最小)
- avg:average(平均)
- cnt:count(カウント)
- i:index(インデックス)
- elem:element(要素)
- val:value(値)
- msg:message(メッセージ)
省略形を上手に使用することでコードの記述量を減らすことができますが、多用しすぎると変数名の意味が分かりづらくなるので注意が必要です。
最後に
この記事では、JavaScriptの変数についての基本から、 let 、 const 、 var の違い、スコープチェーン、変数名の付け方について解説しました。
変数はプログラムの中心的な要素であり、正しく使うことはコードの品質と保守性に大きな影響を与えます。スコープや変数を適切に使うよう意識することで、コードの品質を高めるためのスキルを磨くことができます。
この記事では基本的なデータ型について簡単に触れましたが、変数の解説のために最低限の説明しかしませんでした。JavaScriptでは、データ型に用意されているメソッドやプロパティを使用することでデータを操作することができます。これらを使用するには、JavaScriptにおいてのデータ型の特徴について理解しておくとスムーズに学習することができるでしょう。
以下の記事では、JavaScriptの基本的なデータ型やその特徴について解説し、データを操作する方法の例として文字列と数値の基本的な操作方法をご紹介しています。JavaScript初学者の方は次に以下の記事を読むことをオススメします。
