
変数とデータ型(let, const, プリミティブ型)
2025-07-28はじめに
JavaScriptを学ぶ上で、変数とデータ型の理解は基礎中の基礎です。この知識なしでは効果的なプログラミングはできません。本記事では、現代のJavaScript(ES6以降)で使用される変数宣言方法(let
とconst
)と、JavaScriptの基本的なデータ型について詳しく解説します。最後には理解度を確認するための演習問題を用意しています。
変数宣言:letとconst
変数とは
変数はデータを格納するための「名前付きの容器」です。プログラム内でデータを保持したり、参照したりするために使用します。
var, let, constの違い
ES6以前はvar
のみでしたが、ES6でlet
とconst
が導入されました。
特徴 | var | let | const |
---|---|---|---|
再宣言 | ○ | × | × |
再代入 | ○ | ○ | × |
スコープ※ | 関数 | ブロック | ブロック |
ホイスティング※ | ○ | △ | △ |
現代のJavaScriptではvar
はほとんど使われず、let
とconst
が推奨されます。
※スコープとホイスティングについては後述
letの使用例
let count = 10; // 変数宣言と初期化
count = 20; // 再代入可能
console.log(count); // 20
let message; // 宣言のみ(値はundefined)
message = "Hello";
console.log(message); // "Hello"
constの使用例
const PI = 3.14159; // 宣言と初期化必須
// PI = 3.14; // エラー: 再代入不可
const user = { name: "太郎", age: 25 };
user.age = 26; // オブジェクトのプロパティは変更可能
// user = {}; // エラー: 再代入は不可
letとconstの使い分け
基本はconst
を使用し、再代入が必要な場合のみlet
を使います。これにより、意図しない再代入を防ぎ、コードの安全性が向上します。
データ型:プリミティブ型とオブジェクト
JavaScriptのデータ型はプリミティブ型(基本型)とオブジェクト型に大別されます。
プリミティブ型(基本型)
- 数値(Number): 整数と浮動小数点数
let age = 25;
let price = 99.95;
- 文字列(String): テキストデータ
let name = "山田太郎";
let greeting = 'こんにちは';
- 真偽値(Boolean): true/false
let isActive = true;
let isCompleted = false;
- undefined: 値が未定義
let x; // 自動的にundefined
- null: 値が存在しないことを明示
let user = null;
- シンボル(Symbol): ES6で追加、一意な識別子
const id = Symbol("id");
- BigInt: ES2020で追加、大きな整数
const bigNum = 1234567890123456789012345678901234567890n;
型の確認方法
typeof
演算子でデータ型を確認できます。
console.log(typeof 42); // "number"
console.log(typeof "text"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (歴史的な理由)
console.log(typeof Symbol()); // "symbol"
console.log(typeof 10n); // "bigint"
変数のスコープ
ブロックスコープ
let
とconst
はブロックスコープ({}で囲まれた範囲)を持ちます。
{
let localVar = "内部";
const LOCAL_CONST = "定数";
console.log(localVar); // "内部"
console.log(LOCAL_CONST); // "定数"
}
// console.log(localVar); // エラー
// console.log(LOCAL_CONST); // エラー
スコープのチェーン
JavaScriptは変数を探す際に、現在のスコープから外側のスコープへと順に探します。
let global = "グローバル";
function checkScope() {
let local = "ローカル";
console.log(local); // "ローカル"
console.log(global); // "グローバル"
}
checkScope();
console.log(global); // "グローバル"
// console.log(local); // エラー
- 使用可能な文字: 文字、数字、_、$
- 数字で始められない
- 予約語は使用不可
- 大文字小文字を区別
- 意味のある名前を付ける(推奨で絶対条件ではない)
- 定数は大文字で(慣例)
変数の命名規則
// 良い例
let userName = "太郎";
let あいう = 5;
const MAX_SIZE = 100;
// 悪い例
let 123abc = "test"; // 数字開始
let let = "reserved"; // 予約語
ホイスティング
変数や関数の定義をコードが実行される前にメモリに配置する挙動のことを指します。
その挙動から「宣言の巻き上げ」とも言われます。
関数のホイスティング
f(); //f関数を実行
function f(){
console.log("Hoisting Test"); // Hoisting Test
}
一見すると実行文が関数の定義より前にあり、エラーになりそうですが問題なく動作しています。これはホイスティングによってコードが実行される前に関数の定義がメモリに配置されているため、実行することができています。
varを使った場合
console.log(x); // undefined
var x = 0; // 変数xの宣言
今度は変数xの宣言よりも前にconsole.logでxの値を取得しています。
こちらも一見エラーになりそうですが、undefinedが出力されます。
変数も関数同様、ホイスティングによってコード実行前に変数xのメモリを確保しているので、console.logで問題なく参照することができています。
注意点としては、行っているのはメモリの確保のみで、値は代入されていないので中身はundefined(未定義)となります。undefinedは値が未定義の場合に自動で代入されるキーワードになります。
事前に変数xのメモリ確保とundefinedの代入を行ってからコードを実行できます。var変数ではこういった処理がコード実行前に行われるため、エラーが発生することなく変数の値を出力することができます。
let、const場合
console.log(x); // ReferenceError
let x = 0;
console.log(x); // ReferenceError
const x = 0;
let、const変数の場合は、
[Uncaught ReferenceError: Cannot access ‘x’ before initialization]
というエラーメッセージが表示されます。let、constの場合は初期化されるまではTDZ(Temporal Dead Zone) にあるとみなされるため、エラーが起きます。TDZとは「一時的なデッドゾーン」と言います。TDZ の中にいる間は、変数は値で初期化されておらず、何かアクセスしようとすると ReferenceError が発生することになります。変数は、宣言されたコードの行まで実行されると、値で初期化されます。変数宣言で初期値を指定しなかった場合は、 undefined という値で初期化されます。
テンプレートリテラル
ES6で導入された文字列表現で、変数を埋め込んだり複数行の文字列を簡単に書けます。
const name = "太郎";
const age = 25;
// 従来の方法
console.log("名前: " + name + ", 年齢: " + age);
// テンプレートリテラル
console.log(`名前: ${name}, 年齢: ${age}`);
// 複数行
const message = `
こんにちは、${name}さん。
あなたの年齢は${age}歳ですね。
`;
演習問題
初級問題(3問)
- 以下のコードの出力結果は?
let x = 10;
x = 20;
const y = x + 5;
console.log(y);
- 正しい変数名をすべて選びなさい。
- a)
let 1stPlace;
- b)
let user_name;
- c)
let const;
- d)
let $price;
- e)
let first-name;
- f)
let レモン;
- 次のコードをテンプレートリテラルを使って書き換えなさい。
const product = "りんご";
const price = 150;
console.log(product + "の価格は" + price + "円です");
中級問題(6問)
- 以下のコードの出力結果とその理由を説明しなさい。
console.log(typeof null);
console.log(typeof undefined);
console.log(typeof {});
console.log(typeof []);
- 次のコードの間違いを指摘し、修正しなさい。
const PI;
PI = 3.14159;
- スコープに関する次のコードの出力結果は?
let a = 1;
{
let a = 2;
console.log(a);
}
console.log(a);
- 次のコードの出力結果を答えなさい。
const obj = { prop: "value" };
obj.prop = "new value";
console.log(obj.prop);
obj = { newProp: "test" };
- 以下のコードを実行した場合の
x
の値は?
let x = "10";
x = x + 5;
x = x - 2;
- 次の2つのコードの違いを説明しなさい。
// コード1
let a = b = 10;
// コード2
let c = 10;
let d = 10;
上級問題(3問)
- 次のコードの出力結果とその理由を説明しなさい。
function test() { console.log(a);
console.log(b);
var a = 1;
let b = 2;
}
test();
- 以下のコードの出力結果を順に答えなさい。
let x = 10;
{
console.log(x);
let x = 20;
console.log(x);
}
console.log(x);
- 次のようなユーザー情報を表すオブジェクトをコピーしてください。
このオブジェクトをコピーして新しいオブジェクトを作成し、address.prefecture
を”大阪府”に変更するコードを書きなさい。ただし、元のuser
オブジェクトは変更されないようにしなさい。
javascript const user = {
name: "山田太郎",
age: 30,
address: {
postalCode: "100-0001",
prefecture: "東京都"
}
};
解答例
初級問題解答
- コードの出力結果
(xが20に更新され、yは20 + 5で25になる)
let x = 10;
x = 20;
const y = x + 5;
console.log(y); // Output: 25
- 正しい変数名
- b)
user_name
- d)
$price
- f) レモン;
- テンプレートリテラル版
console.log(`${product}の価格は${price}円です`);
中級問題解答
- コードの出力結果とその理由
console.log(typeof null); // object (歴史的経緯)
console.log(typeof undefined); // undefined
console.log(typeof {}); // object
console.log(typeof []); // object (配列もオブジェクトの一種)
- 次のコードの間違い
間違い: const
は宣言と同時に初期化が必要。
修正例:
const PI = 3.14159;
- スコープに関する次のコードの出力結果
let a = 1;
{
let a = 2;
console.log(a); // 2
}
console.log(a); // 1
ブロックスコープの内側と外側で別々の変数(a)として認識されている。
- コードの出力結果
"new value"
まで表示された後、obj
への再代入でエラーとなる。
const obj = { prop: "value" };
obj.prop = "new value";
console.log(obj.prop); // new valueが表示される
obj = { newProp: "test" }; // 再代入しているのでエラー
- コードを実行した場合の
x
の値
let x = "10"; // x = "10"
x = x + 5; // x = "105"
x = x - 2; // x = 103
- 2つのコードの違い
コード1: b
は暗黙的にグローバル変数になる
理由は宣言を省略して定義した変数は全て、グローバル変数として見做されるから
コード2: c
とd
は別々の変数
上級問題解答
- コードの出力結果とその理由
// 表示結果
undefined
Uncaught ReferenceError ReferenceError: Cannot access 'b' before initialization
a
: undefined
(varはホイスティングされる)
b
: エラー (letはホイスティングされるがTDZ(Temporal Dead Zone) にある)
- コードの出力結果
(エラーで実行中断)
Uncaught ReferenceError ReferenceError: Cannot access 'x' before initialization
- オブジェクトをコピーして新しいオブジェクトを作成
オブジェクト型変数をコピーする場合はディープコピーして新しいオブジェクトを作成します
javascript const newUser = {
...user,
address: {
...user.address,
prefecture: "大阪府"
}
};