変数 (英: variable) は、オブジェクトやプリミティブに名前をつけ、名前での参照を可能にする機能です。

基本の基本

編集

変数の宣言

編集

「変数」は、オブジェクトに名前をつけて参照の手助けをする機能です。型や値は変数ではなく、オブジェクトとプリミティブが保持しています[1]。静的な言語に慣れた人は、やや戸惑いを感じるかもしれません。

JavaScriptで変数を宣言するには let, const または var キーワードを使用します。

宣言と代入

編集
初期化なし宣言と代入
let a;           // 変数 a を(初期化なしで)宣言
console.log(a);  // 未初期化の変数の値は undefined
a = 15;          // 変数 a に 15 を代入
console.log(a);  // 変数 a の値が undefined から 15 に変更
a = "abc";       // 変数 a に "abc" を代入
console.log(a);  // 変数 a の値が 15 から "abc" に変更
実行結果
undefined
15
abc
ポイント
変数を初期化しないで宣言すると、変数の値は undefined になります。
let 宣言された変数への代入は何度でもできます。
その場合、先に代入されている値と次に代入される値の「型」が同じでなくても問題ありません。
この例で変数 a は undefined → 15 → "abc" と値が推移しています。
初期化あり宣言と代入
let a = -1;      // 変数 a を -1 で初期化して宣言
console.log(a);  // 変数 a の値は初期値の -1
a = 15;          // 変数 a に 15 を代入
console.log(a);  // 変数 a の値が -1 から 15 に変更
let b = a;       // 変数 b を a の値で初期化して宣言
console.log(b);  // 変数 b の値は 15
a = "abc";       // 変数 a に "abc" を代入
console.log(a);  // 変数 a の値が 15 から "abc" に変更
console.log(b);  // 変数 b の値は 15 のまま
b = a = 43;      // 変数 a に 43 を代入し、その値を変数 b に代入
console.log(b);  // 変数 b の値は 43
console.log(a);  // 変数 a の値は 43
実行結果
-1
15
15
abc
15
43
変数を初期値を明示して宣言すると、変数の値は初期値になります。
初期値には変数も使えます。
代入は演算子で右側から評価されます。
b = a = 43b = (a = 43) と同じです。

構文

編集

ここで出てきた構文は、3つです。

letによる変数宣言(初期化なし)
:
let 変数名
letによる変数宣言(初期化あり)
:
let 変数名 = 初期値
代入(代入演算子による代入式)
:
変数名 = 

初期化と代入は、両方とも =(等号)を使うので混同しがちですが、

  • ❌:let a = b = 100
  • ⭕:a = b = 100

重複した初期化はできませんが、重複した代入は可能です。

様々な初期化と代入
// 2つ以上の宣言を , で区切って一度にできます
let a, b;
console.log(a, b);  // a と b の初期値は undefined

// 初期化は、この様に書きます
let x = 3, y = 4;
console.log(x, y);  // x は 3、y は 4

// 分割代入風の構文もあります
let [i, j] = [123, 567];
console.log(i, j);  // i は 123、j は 567

let p = [1, 2, 3, 4, 5];
let [q, r] = p;
console.log(p, q, r);  // p は [1, 2, 3, 4, 5]、q は 1、r は 2
実行結果
undefined undefined
3 4
123 567
[ 1, 2, 3, 4, 5 ] 1 2

let キーワードで宣言された変数はブロックスコープを持ちます。{ } の中がブロックで、ブロックを出ると let で宣言した変数は参照できなくなります。

for文中の式は単文で { } が使われていない場合も for 文のブロックスコープを持ちます。for 文の条件式でも let で宣言された変数は for 文を出ると参照できなくなります。

'use strict';

for (let i = 0; i < 10; i++) // 波括弧{ }でなくてもfor文はブロックスコープ
  console.log(i);
console.log(i); // ReferenceError: i is not defined

let は、ひとつのスコープ内での再宣言はできません。

// 二行目でエラーになります
let x = 1; // これは初期化を伴うlet変数宣言
let x = 2; // 再宣言しているので SyntaxError: ここでスクリプトは中止

// x + 3 を計算
console.log(x + 3); // 既にエラーなので「5」は表示されない

let 宣言された変数のインスタンスとの束縛を変えるには、let 変数宣言ではなく代入を行います。 strict モードでも代入が可能です。

つまり、下記のコードは表示が可能です。

'use strict';

let x = 1; // 初期化を伴う let 変数宣言

x = 2; // 代入
// x + 3 を計算
console.log(x + 3); // 5 を表示

当然、(非strictモードという意味の)通常モードでも代入が可能です。

// このコードは可能
let x = 1; 
x = 2; // 代入

// x + 3 を計算
console.log(x + 3); // 5 を表示

const は、イミュータブル(不変)な値を持つ変数を定義するために使用されます。const で定義された変数は、再代入ができません。

// このコードはエラーになります
const y = 10;
y = 15; // TypeError: Assignment to constant variable

const で定義された変数にオブジェクトや配列を代入する場合、そのオブジェクトや配列のプロパティは変更可能です。

const z = { name: "太郎" };
z.name = "次郎"; // オブジェクトのプロパティは変更可能
console.log(z.name); // 次郎

const arr = [1, 2, 3];
arr.push(4); // 配列に新しい要素を追加
console.log(arr); // [1, 2, 3, 4]

このため、const のスコープはブロック内に限ります。

if (true) {
  const w = 5;
}
console.log(w); // ReferenceError: w is not defined

constの使い方

編集

const は以下の構文で使います。

構文
:
const 変数名 = 
const を使って数値を保持する例
const pi = 3.14159; // 不変の値
console.log(pi); // 3.14159
const を使ってオブジェクトを保持する例
const person = {
  name: "太郎",
  age: 25
};
console.log(person.name); // 太郎

person.age = 26; // オブジェクトのプロパティは変更可能
console.log(person.age); // 26

var 変数宣言は、グローバルスコープまたは関数スコープを持つため、注意が必要です。var を使って変数を宣言すると、その変数は関数の外でもアクセス可能です。

var x = 1;
if (true) {
  var x = 2; // 同じスコープ内のため、上書きされる
}
console.log(x); // 2 が表示される

一方、letconst で宣言された変数は、それぞれのブロックスコープを持ち、上書きされません。

varの使い方

編集

var を使用して変数を宣言する場合、以下の構文で行います。

構文
:
var 変数名 = 
初期化なしの例
var a;
console.log(a); // undefined
初期化ありの例
var b = 10;
console.log(b); // 10

まとめ

編集

JavaScriptの変数宣言には var, let, const があり、それぞれの特徴やスコープに注意が必要です。letconst の使用を推奨しますが、古いコードでは var を見かけることがあります。

脚註

編集
  1. ^ オブジェクトとプリミティブをあわせてインスタンスということがあります。

参考文献

編集
  NODES
Javascript 7