JavaScript 変数とデータ型

2023年4月26日

English version.

変数とは、プログラム内で値を保存するための名前のことです。

プログラムでは、処理を行うために必要なデータを扱います。例えば、数値文字列真偽値などです。これらのデータは、変数を使ってプログラム内に保存することができます。

変数は、値を保存するための「箱」とも言えます。箱には、名前が付けられており、その名前を使って箱に保存された値を参照できます。例えば、以下のように、変数xに数値の10を代入しています。

let x = 10;

このように、変数を使用することで、複雑な計算や処理を行うときに必要な値を保存し、再利用することができます。また、変数の値をプログラムの途中で変更することもできます。

変数の名前は、プログラムの作成者が自由に付けることができます。ただし、わかりやすく、プログラムの他の部分と区別できる名前を付けることが重要です。

宣言(作成)

変数の宣言とは、値を保存するための名前を付けることで、その名前を使って値を参照することができるようにすることです。

たとえば、以下のようなコードでは、変数x10という値を代入し、その後、xを使用して値を出力しています。

let x = 10;
console.log(x); // 10

変数を宣言するには、varletconstのキーワードを使用します。それぞれのキーワードには、異なる性質があります。

varは、JavaScriptの古いバージョンで使用されている変数宣言方法で、グローバルスコープまたはローカルスコープで使用できます。

letは、ブロックスコープで使用できる変数宣言方法で、同じ名前の変数を再宣言することができません。また、letで宣言された変数は、宣言前に使用することはできません。

constは、ブロックスコープで使用できる変数宣言方法で、一度値を設定すると再代入することができません。ただし、オブジェクトのプロパティや配列の要素は変更可能です。

var

varは、JavaScriptの古いバージョンで使用されている変数宣言方法で、グローバルスコープまたはローカルスコープで使用できます。

varを使用して変数を宣言する場合、以下のように記述します。

var x = 10;

このように、varを使用して変数xに数値の10を代入しています。

varで宣言した変数は、宣言前に使用することができます。ただし、その場合は値がundefinedになります。

console.log(y); // undefined
var y = 20;

varで宣言した変数は、同じ名前の変数を再宣言することができます。ただし、グローバルスコープで再宣言すると、既存の変数の値が変更されます。

var z = 30;
var z = 40; // 再宣言できる
console.log(z); // 40

varで宣言した変数は、グローバルスコープまたはローカルスコープで使用できます。ただし、ローカルスコープで宣言した場合、その変数はその関数内でのみ使用できます。

varは、ES6以降のletconstよりも柔軟性がある反面、構文の特徴が少し複雑であるという欠点があります。したがって、現在はletconstを使用することが推奨されています。

varを使うべきではない理由

以下の理由から、現在のJavaScriptでは、letconstを使用することが推奨されています。letconstは、ブロックスコープを持ち、再宣言や宣言前の使用ができないため、プログラムの品質を向上させることができます。

  • スコープの問題
  • 再宣言の問題
  • 宣言前の使用の問題
  • ブロックスコープの欠如
スコープの問題

varで宣言した変数は、宣言した場所によってグローバルスコープか関数スコープかを判断するため、スコープの問題が発生します。また、関数スコープで宣言した変数が外側からアクセスできてしまう問題もあります。これにより、プログラムの可読性が低下し、変数名の競合が発生しやすくなります。

再宣言の問題

varで宣言した変数は、同じ名前の変数を再宣言することができます。このため、意図しない変数の上書きが発生する可能性があります。特に、複雑なプログラムで同じ変数名を誤って使用してしまうと、問題が発生する可能性が高くなります。

宣言前の使用の問題

varで宣言した変数は、宣言前に使用することができます。ただし、その場合、変数の値がundefinedになるため、プログラムのバグの原因になることがあります。

ブロックスコープの欠如

varで宣言した変数は、ブロックスコープを持たないため、同じ名前の変数が複数のブロック内で競合してしまう可能性があります。これにより、予期しない値が変数に代入されることがあります。

var を使う状況

letconstは、比較的新しい機能であるため、古いバージョンのブラウザではサポートされていない場合があります。この場合、varを使用することが必要になります。

ツール上でJavaScriptを使う場合も古いバージョンのみのケースがあり、そういった場合もletconstではなくvarを利用することになります。

let

letは、ブロックスコープを持つ変数宣言キーワードです。letを使用して宣言された変数は、その変数が宣言されたブロック内でのみ有効です。以下は、letを使用した変数の宣言方法です。

let x = 10;

この例では、letを使用してxという変数を宣言しています。xは値10を持ちます。

letを使用して宣言された変数は、宣言前に使用することはできません。これは、宣言前に使用すると参照エラーが発生するためです。

console.log(y); // Uncaught ReferenceError: y is not defined
let y = 20;

また、letを使用して宣言された変数は、同じ名前の変数を再宣言することができません。再宣言を行うと、構文エラーが発生します。

let z = 30;
let z = 40; // Uncaught SyntaxError: Identifier 'z' has already been declared

letは、varと比較してスコープの問題や再宣言の問題が発生しにくく、可読性の高いコードを書くことができます。したがって、letを使用することが推奨されます。

const

constは、定数を宣言するためのキーワードです。constを使用して宣言された定数は、再代入することができません。以下は、constを使用した定数の宣言方法です。

const PI = 3.14159;

この例では、constを使用してPIという定数を宣言しています。PIは値3.14159を持ちます。

定数は再代入できないため、以下のように再代入を行うと構文エラーが発生します。

const age = 30;
age = 40; // Uncaught TypeError: Assignment to constant variable.

constを使用して宣言された定数は、オブジェクトや配列でも使用することができます。ただし、再代入はできないため、オブジェクトや配列内の要素を変更することはできますが、オブジェクトや配列そのものを再代入することはできません。

const person = {
  name: 'John',
  age: 30
};

person.age = 40; // OK

person = { name: 'Jane', age: 40 }; // Uncaught TypeError: Assignment to constant variable.

constは、変更されない値を宣言する場合に使用することが推奨されます。定数は、再代入の問題を回避するために使用されるため、不変であることが重要です。

スコープ

変数のスコープとは、その変数がアクセス可能なコードの範囲のことを指します。

スコープにはグローバルスコープ、ローカルスコープ(関数スコープ、ブロックスコープ)があり、それぞれ特徴があります。スコープを正しく理解することで、コードの理解と保守性を向上させることができます。

グローバルスコープ

グローバルスコープとは、JavaScriptのコード内でどこからでもアクセス可能な変数や関数が定義されるスコープです。つまり、グローバルスコープで定義された変数は、プログラム内のどの場所からでも参照できます。以下は、グローバルスコープで定義された変数の例です。

ler x = 10;

function foo() {
  console.log(x); // 10
}

foo(); // 10

この例では、グローバルスコープで変数xを定義しています。foo()関数内でも、xにアクセスできます。

グローバルスコープには、いくつかの問題があります。例えば、複数のファイルで同じ名前の変数が使用されると、予期しない動作が発生する可能性があります。また、グローバルスコープで定義された変数は、意図しない場所で値が変更されたり、別の関数で同じ名前の変数が使用されたりする可能性があるため、プログラムの保守性が低下する可能性があります。

したがって、グローバルスコープで変数を定義する場合は、名前の競合を避けるために、グローバル変数の名前には一意な接頭辞をつけるなどの工夫が必要です。また、できるだけローカルスコープで変数を宣言することが推奨されます。

JavaScriptファイルが異なる場合、異なるファイルに定義されたグローバルスコープの変数は、互いに影響を与えることができます。

例えば、script1.jsファイルでグローバルスコープに変数xを定義し、script2.jsファイルで同じ名前のグローバルスコープの変数xを定義した場合、どちらか一方で変数に代入した値は、もう一方でもアクセスすることができます。これは、異なるファイルに定義されたJavaScriptのコードは、同じグローバルスコープを共有するためです。

このため、異なるJavaScriptファイルでグローバルスコープの変数を使用する場合は、変数名の競合に注意する必要があります。変数名の競合を回避する方法の1つは、異なるファイルで同じ変数名を使用しないことです。また、ES6以降では、letやconstを使用して、グローバルスコープの汚染を回避することができます。

ローカルスコープ

ローカルスコープとは、ブロック、関数、または関数内で作成された別のブロック内で宣言された変数の範囲です。ローカルスコープで宣言された変数は、同じブロックまたは関数内でのみアクセス可能です。

ローカルスコープには、いくつかの利点があります。例えば、変数名の競合を避けるために、ローカルスコープで変数を宣言することができます。また、関数内で使用される変数は、他の部分で意図せず変更されたり、名前の競合が発生したりすることがなくなり、コードの保守性が向上します。

ローカルスコープでの変数の宣言には、letやconstを使用することが推奨されます。これらのキーワードを使用すると、意図しない再宣言や再代入を避けることができます。

関数スコープ

関数スコープとは、関数内で定義された変数が、その関数内でのみアクセス可能なスコープのことを指します。関数スコープにより、変数名の競合を回避できるため、コードの保守性を高めることができます。

以下は、関数スコープの例です。

function foo() {
  var x = 10;
  console.log(x); // 10
}

foo(); // 10
console.log(x); // Uncaught ReferenceError: x is not defined

この例では、関数foo()内で変数xが定義され、値10が割り当てられています。xfoo()関数内でのみアクセス可能であり、関数外からアクセスするとエラーが発生します。

関数スコープは、グローバルスコープやブロックスコープとは異なり、変数を宣言した関数内でのみ使用可能です。このため、関数内で変数を宣言すると、他の関数やグローバルスコープで同じ変数名を使用しても名前の競合が発生することがありません。

ブロックスコープ

ブロックスコープとは、{}で囲まれたブロック内で宣言された変数が、そのブロック内でのみアクセス可能なスコープのことを指します。ブロックスコープにより、変数名の競合を回避できるため、コードの保守性を高めることができます。

以下は、ブロックスコープの例です。

function foo() {
  if (true) {
    var x = 10;
    let y = 20;
    const z = 30;
  }
  console.log(x); // 10
  console.log(y); // Uncaught ReferenceError: y is not defined
  console.log(z); // Uncaught ReferenceError: z is not defined
}

foo();

この例では、if文のブロック内でvarletconstキーワードを使用してそれぞれ変数xyzを宣言しています。しかし、yzif文のブロックの外で参照しようとすると、参照エラーが発生します。一方、xは関数スコープ内で定義されており、if文のブロックの外でも参照することができます。

ブロックスコープは、ES6以降に追加されたletconstなどの新しいキーワードによってサポートされています。これらのキーワードを使用することで、変数の範囲をブロック内に制限し、意図せぬ変数の再宣言や再代入を避けることができます。

ブロックスコープを使用することで、変数の範囲を必要な範囲に限定することができるため、コードの可読性と保守性を向上させることができます。

変数名の命名規則

変数名には次の文字が利用可能です。

  • 英字(a~z、A~Z)
  • 数字(0~9)
  • アンダースコア(_)
  • ドル記号($)

変数名の命名規則は以下の通りです。

  1. 変数名は、英字、$_で始める必要があります。
  2. 予約語(例:ifwhileforなど)を使用することはできません。
  3. 変数名は意味のある名前にすることが望ましいです。特に、変数の役割や目的を反映した名前をつけることが重要です。
  4. 変数名は簡潔で分かりやすいものにすることが望ましいです。

以下は、変数名の命名規則の例です。

// 有効な変数名の例
let firstName = 'John';
let age = 30;
let $currency = 'USD';
let _maxLimit = 100;

// 無効な変数名の例
let 1stNumber = 10; // 数字から始めることはできません
let full-name = 'John Doe'; // ハイフンを使うことはできません
let if = true; // 予約語を変数名に使用することはできません

変数の初期化

変数の初期化とは、変数に最初の値を代入することを指します。JavaScriptでは、変数の宣言と同時に初期値を設定することができます。

例えば、以下のように変数を宣言し、初期値を設定することができます。

let age = 30;

この場合、変数ageには初期値として30が代入されます。

また、変数を宣言した後に、後から値を代入することもできます。

let age;
age = 30;

この場合、変数ageには最初にundefinedが代入され、その後に30が代入されます。

さらに、変数を宣言しただけで初期値を設定しない場合、その変数には自動的にundefinedが代入されます。

let age;
console.log(age); // 結果:undefined

データ型

データ型とは、プログラムにおいて扱うデータの種類を表す概念です。コンピュータには、数値、文字列、真偽値など、多様な種類のデータがあります。プログラムでは、これらのデータを処理するために、データ型を指定する必要があります。

例えば、数値を計算するプログラムでは、数値データ型を使用します。文字列を表示するプログラムでは、文字列データ型を使用します。真偽値を判定するプログラムでは、真偽値データ型を使用します。

JavaScriptにおいて使用できるデータ型は、以下のように分類されます。

プリミティブ型

オブジェクト型

プリミティブ型は、単一の値を表し、それぞれが独自のデータ型を持ちます。一方、オブジェクト型は複数の値をまとめたものであり、それ自体がデータ型を持ちません。

JavaScriptでは、変数のデータ型は宣言時に決定されず、変数に値を代入することで動的に決定されます。また、同じ変数に異なるデータ型の値を代入することができます。

---

関連記事

JavaScriptの記事一覧