const

const 宣言はブロックスコープのローカル変数(定数)を宣言します。定数の値は代入演算子を使用して再代入することができませんが、定数がオブジェクトであった場合、そのプロパティを追加したり、更新したり、削除したりすることができます。

試してみましょう

構文

js
const name1 = value1;
const name1 = value1, name2 = value2;
const name1 = value1, name2 = value2, /* …, */ nameN = valueN;
nameN

宣言する変数名。それぞれ、正当な JavaScript 識別子または分割結合パターンでなければなりません。

valueN

変数の初期値。正式な式であれば何でもかまいません。

解説

const 宣言は let とよく似ています。

  • const declarations are scoped to blocks as well as functions.
  • const 宣言は宣言した位置に到達してからでないとアクセスすることができません(一時的デッドゾーンを参照してください)。このため、 const 宣言は一般的に巻き上げされないと見なされます。
  • スクリプトの最上位で宣言された場合、 const 宣言は globalThis にプロパティを作成しません。
  • const 宣言は、同じスコープ内の他の宣言によって再宣言することはできません。
  • const文ではなく宣言を始めます。つまり、ブロックの本体として単独の const 宣言を使用することはできません(変数にアクセスする方法がないので、意味はあります)。
    js
    if (true) const a = 1; // SyntaxError: Lexical declaration cannot appear in a single-statement context
    

定数の初期化子が必要です。同じ宣言の中でその値を指定しなければなりません。(後で変更できないことを考えると、これは意味のあることです。)

js
const FOO; // SyntaxError: Missing initializer in const declaration

const 宣言は値への不変の参照を作成します。これはその値が不変であるという意味ではなく、変数の識別子が再割り当てできないという意味です。例えば、内容がオブジェクトの場合、これはオブジェクトの内容(例えばプロパティ)は変更できることを意味しています。 const 宣言は「アイデンティティが一定の変数を作成する」のであって、「値が一定の変数を作成する」のではありません。また、「不変のバインド」を作成するのであって、「不変の値」を作成するのではありません。

多くのスタイルガイド(MDN のものも含む)では、変数がそのスコープで再代入されない場合は、 constlet の代わりに使用することを推奨しています。これにより、変数の型(プリミティブの場合は値)が変更されることはないという意図が明確になります。他にも、プリミティブ以外の変数が変更される場合は let を推奨する人もいます。

const キーワードに続くリストはバインディングリストと呼ばれ、カンマで区切られます。カンマはカンマ演算子ではなく、 =代入演算子ではありません。後の変数の初期化子は、リスト内の前の変数を参照することができます。

基本的な定数の使い方

定数は大文字または小文字で宣言することができますが、特にプリミティブの場合は、本当に変更不可能であるので、すべて大文字で宣言するのが慣例です。

js
// MY_FAV を定数として定義して、その値を 7 にします
const MY_FAV = 7;

console.log("my favorite number is: " + MY_FAV);
js
// Re-assigning to a constant variable throws an error
MY_FAV = 20; // TypeError: Assignment to constant variable

// Redeclaring a constant throws an error
const MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared
var MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared
let MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared

ブロックスコープ

ブロックスコープの性質に注意することが重要です。

js
const MY_FAV = 7;

if (MY_FAV === 7) {
  // これは問題なく、ブロックスコープの MY_FAV 変数を作成します
  const MY_FAV = 20;
  console.log(MY_FAV); // 20

  // これはグローバルコンテキストに巻き上げられ、エラーが発生します
  var MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared
}

console.log(MY_FAV); // 7

オブジェクトと配列の定数

const はオブジェクトや 配列にも作用します。オブジェクトを上書きしようとすると、"Assignment to constant variable" というエラーが発生します。

js
const MY_OBJECT = { key: "value" };
MY_OBJECT = { OTHER_KEY: "value" };

しかし、オブジェクトのキーは保護されていないので、次の文は問題なく実行されます。

js
MY_OBJECT.key = "otherValue";

オブジェクトを不変にするには、 Object.freeze() を使用する必要があります。

配列も同様です。新しい配列を変数に割り当て要とすると、"Assignment to constant variable" のエラーが発生します。

js
const MY_ARRAY = [];
MY_ARRAY = ["B"];

しかし、配列にアイテムを追加することはでき、変更は可能です。

js
MY_ARRAY.push("A"); // ["A"]

分割代入による宣言

それぞれの = の左辺はバインドパターンにもなります。これにより、一度に複数の変数を作成することができます。

js
const result = /(a+)(b+)(c+)/.exec("aaabcc");
const [, a, b, c] = result;
console.log(a, b, c); // "aaa" "b" "cc"

詳しくは、分割代入を参照してください。

仕様書

Specification
ECMAScript Language Specification
# sec-let-and-const-declarations

ブラウザーの互換性

BCD tables only load in the browser

関連情報