JavaScript | ES6+ 文法:オブジェクト拡張 – 計算されたプロパティ名

JavaScript JavaScript
スポンサーリンク

計算されたプロパティ名とは何か

「計算されたプロパティ名(computed property name)」は、
オブジェクトリテラルのキーを、文字列リテラルではなく「式の結果」から動的に決める書き方です。

普通はこう書きます。

const obj = {
  name: "Alice",
  age: 20
};
JavaScript

キー nameage は、コードにそのまま書かれた「固定の文字列」です。

計算されたプロパティ名を使うと、こう書けます。

const key = "userName";

const obj = {
  [key]: "Alice"  // key の中身("userName")がプロパティ名になる
};

console.log(obj);        // { userName: "Alice" }
console.log(obj.userName); // "Alice"
JavaScript

ここが重要です:
角かっこ [...] の中に書いた「式の評価結果」が、そのままプロパティ名(キー)になります。
key という名前のプロパティを作っているのではなく、key という変数の中身(”userName”)をキーにしている、というイメージを持ってください。


基本構文と「いつ使うのか」のイメージ

角かっこの中は「何でも OK な式」

計算されたプロパティ名は、必ず [] を使って書きます。

const obj = {
  [式]: 値
};
JavaScript

この「式」の部分には、変数でも、文字列操作でも、テンプレートリテラルでも OK です。

const id = 7;
const prefix = "user_";

const obj = {
  [prefix + id]: "Alice"  // "user_7" というキーができる
};

console.log(obj);           // { user_7: "Alice" }
console.log(obj["user_7"]); // "Alice"
JavaScript

ここが重要です:
「キーを動的に決めたいとき」は、とりあえず [...] の中に「欲しい文字列を作る式」を書けばいい、と覚えておくと楽です。

いつ使うと嬉しいのか(ざっくり)

計算されたプロパティ名が特に効いてくるのは、例えばこんな場面です。

  • 変数の中身を「そのままキー名」にしたいとき(ただし、短縮記法では足りない場合)
  • user_1」「user_2」のように、番号付きのキー名を量産したいとき
  • 入力(フォーム名、API のフィールド名など)からキー名を作りたいとき
  • 定数(列挙的な値)をキーとして使いたいとき

ひとつずつ、具体例で見ていきます。


変数からキー名を作る(短縮記法との違い)

「変数名」ではなく「変数の中身」をキーにしたい

プロパティ短縮記法({ foo })は、「変数名と同じ名前のキー」を作るだけでした。

const key = "userName";
const value = "Alice";

// 短縮記法だと「key」という名前のプロパティになる
const obj1 = { key: value };
console.log(obj1); // { key: "Alice" }
JavaScript

userName というキー名にしたい」のに、key というキーになってしまうのが問題です。

ここで計算されたプロパティ名の出番です。

const key = "userName";
const value = "Alice";

const obj2 = {
  [key]: value   // "userName": "Alice" と同じ意味
};
console.log(obj2); // { userName: "Alice" }
JavaScript

ここが重要です:
短縮記法 { key } は「プロパティ名=key」、
計算されたプロパティ名 { [key]: ... } は「プロパティ名=key 変数の中身」で、意味が違います。

定数(マップキー)をオブジェクトのキーにする

例えば、フィールド名をまとめた定数を定義しておいて、それをキーに使うパターンです。

const FIELDS = {
  ID: "id",
  NAME: "name"
};

const user = {
  [FIELDS.ID]: 1,
  [FIELDS.NAME]: "Alice"
};

console.log(user); // { id: 1, name: "Alice" }
JavaScript

FIELDS.ID をキーにしたい」という意図が、コードにそのまま現れます。
定数を変更すれば、キー名も自動的に変わるのもポイントです。


動的なキー名の生成(テンプレート文字列との組み合わせ)

連番のキーを作る

API から受け取る形式などで、「item1, item2, item3 …」のようなキーを作りたいことがあります。

const obj = {};
const count = 3;

for (let i = 1; i <= count; i++) {
  obj[`item${i}`] = i * 10;
}

console.log(obj);
// { item1: 10, item2: 20, item3: 30 }
JavaScript

このような「コードから見て規則があるキー名」を作りたいときに、
テンプレートリテラル(バッククォート)+計算されたプロパティ名はとても相性が良いです。

言語コードをキーにした翻訳テーブルなど

const lang = "ja";
const key = `title_${lang}`; // "title_ja"

const messages = {
  [key]: "こんにちは",
  title_en: "Hello"
};

console.log(messages.title_ja); // "こんにちは"
JavaScript

ここが重要です:
「キー名に現実のルール(パターン)があるとき」は、テンプレート文字列+計算されたプロパティ名でそのルールをコードに表現できる、ということです。


関数の中で「キー名を変数で受け取る」パターン

引数で渡されたキー名でオブジェクトを作る

例えば、「任意のキー名と値を受け取って、新しいオブジェクトを返す」関数。

function makeObject(key, value) {
  return {
    [key]: value
  };
}

console.log(makeObject("name", "Alice")); // { name: "Alice" }
console.log(makeObject("age", 20));       // { age: 20 }
JavaScript

もし計算されたプロパティ名がなかったら、まず空オブジェクトを作ってから代入する必要があります。

// 計算されたプロパティ名なしでやろうとすると…
function makeObjectOld(key, value) {
  const obj = {};
  obj[key] = value;
  return obj;
}
JavaScript

どちらでも結果は同じですが、
return { [key]: value }; の方が「やりたいこと」が一発で見えます。

フィールド名が引数で決まる更新処理

例えば、「状態オブジェクトの指定フィールドだけ更新する」関数。

function updateField(state, key, newValue) {
  return {
    ...state,
    [key]: newValue
  };
}

const state1 = { name: "Alice", age: 20 };
const state2 = updateField(state1, "age", 21);

console.log(state2); // { name: "Alice", age: 21 }
JavaScript

ここが重要です:
キー名を変数で受け取る関数を作りたいとき、計算されたプロパティ名はほぼ必須になります。


プロパティアクセスとの関係(「.」と「[]」のイメージ)

定義するときの [...] と、読むときの obj[...]

計算されたプロパティ名で定義したプロパティは、
アクセスするときにも "ドット記法" ではなく「ブラケット記法」で読むことがあります。

const field = "score";

const result = {
  [field]: 100
};

console.log(result.score);      // 100(キーが分かっているとき)
console.log(result[field]);     // 100(変数からアクセスするとき)
console.log(result["score"]);   // 100(文字列からアクセス)
JavaScript

定義するときの [...] と、アクセスするときの obj[...] はセットで覚えると良いです。

ここが重要です:
「ドット記法」は“固定のキー名”のときだけ、「ブラケット記法」は“文字列や変数からキーを決めたいとき”に使う、という使い分けがそのまま定義にもアクセスにも当てはまります。


よくある勘違いと注意点(重要ポイントの深掘り)

角かっこを忘れると「全く違う意味」になる

const key = "name";

// これは NG(短縮記法で "key" プロパティになってしまう)
const user1 = { key: "Alice" };  // { key: "Alice" }

// 「name」というキーにしたいならこう
const user2 = { [key]: "Alice" }; // { name: "Alice" }
JavaScript

変数名をそのままキーにする短縮記法({ key })と、
変数の中身をキーにする計算されたプロパティ名({ [key]: ... })が混ざりやすいので、
[] があるかどうか」を必ず確認してください。

式の結果は文字列(またはシンボル)になる

[式] の「式」は、最終的に文字列(もしくはシンボル)として解釈されます。

const obj = {
  [1 + 2]: "three"
};

console.log(obj);      // { '3': 'three' }
console.log(obj[3]);   // "three"
console.log(obj["3"]); // "three"
JavaScript

数値を書いても、最終的には "3" のような文字列キーとして扱われる、というイメージで構いません。

あまり「なんでもかんでも動的」にしすぎない

計算されたプロパティ名は強力ですが、
何でもかんでも動的にすると、逆に「キーが何になるのか」がパッと見て分からなくなります。

// 極端な例(あまりおすすめしない)
const obj = {
  [Math.random() > 0.5 ? "a" : "b"]: 1
};
JavaScript

初心者のうちは、

  • 「明らかに規則があるキー名」
  • 「単に変数名をキーとして使いたい」

くらいに使いどころを絞ると、読みやすさとパワーのバランスがとりやすくなります。


例題で理解を固める

// 1) 変数の中身をキーにする基本
const key = "title";
const article = {
  [key]: "ES6 入門"
};
console.log(article); // { title: "ES6 入門" }

// 2) テンプレート文字列でキーを作る
const lang = "ja";
const messages = {
  [`hello_${lang}`]: "こんにちは",
  [`hello_en`]: "Hello"
};
console.log(messages.hello_ja); // "こんにちは"

// 3) 定数テーブルをキーに使う
const FIELDS = {
  ID: "id",
  NAME: "name"
};
const user = {
  [FIELDS.ID]: 1,
  [FIELDS.NAME]: "Alice"
};
console.log(user); // { id: 1, name: "Alice" }

// 4) 関数で渡されたキー名で更新する
function updateField(state, key, value) {
  return {
    ...state,
    [key]: value
  };
}
const state1 = { name: "Alice", age: 20 };
const state2 = updateField(state1, "age", 21);
console.log(state2); // { name: "Alice", age: 21 }

// 5) 連番キーのオブジェクトを作る
function makeIndexMap(count) {
  const map = {};
  for (let i = 0; i < count; i++) {
    map[`item_${i}`] = i;
  }
  return map;
}
console.log(makeIndexMap(3));
// { item_0: 0, item_1: 1, item_2: 2 }
JavaScript

まとめ

計算されたプロパティ名の核心は、
「オブジェクトのキー名を、固定の文字列ではなく“式の結果”から動的に決められる」 ことです。

{ [key]: value } で「変数の中身をキーにする」、
{ [item${i}]: value } で「パターンのあるキー名をコードで表現する」、
{ ...state, [key]: newValue } で「引数で渡されたキーだけを更新する」──
こうした書き方が、ES6 以降のオブジェクト操作ではよく使われます。

短縮記法 { key } との違い(変数名 vs 変数の中身)、
[] を付け忘れると全く別物になること、
動的にしすぎると読みにくくなること。
このあたりを意識しながら使えば、初心者でも「意図が伝わる動的オブジェクト」を自然に書けるようになります。

タイトルとURLをコピーしました