オブジェクト初期化子

オブジェクトは、new Object()、Object.create()、 またはリテラル記法(初期化記法)を使用することで初期化することが可能です。 オブジェクト初期化子は、0個以上のオブジェクトのプロパティ名と関連する値のペアを、中括弧({})で囲ったリストです。

文法

var o = {};
var o = { a: "foo", b: 42, c: {} };

var a = "foo", b = 42, c = {};
var o = { a: a, b: b, c: c };

var o = {
  property: function ([parameters]) {},
  get property() {},
  set property(value) {},
};

ECMAScript 6の新しい記法

これらの記法をサポート状況については、互換性テーブルを確認してください。 サポートされない環境では、これらの記法は文法エラーを引き起こします。

// プロパティ名の略記 (ES6)
var a = "foo", b = 42, c = {};
var o = { a, b, c };

// メソッド名の略記 (ES6)
var o = {
  property([parameters]) {},
  get property() {},
  set property(value) {},
  * generator() {}
};

// プロパティ名を算出(Computed) (ES6)
var prop = "foo";
var o = {
  [prop]: "hey",
  ["b" + "ar"]: "there",
};

説明

オブジェクト初期化子は、オブジェクトの初期化を表現する式です。 オブジェクトは、オブジェクトを表現するプロパティから構成されます。 オブジェクトのプロパティの値は、プリミティブのデータ型、またはその他のオブジェクトを含めることが可能です。

オブジェクトの作成

プロパティを持たない空のオブジェクトを、次のようして作成することが可能です。

var object = {};

しかし、リテラルまたは初期化子記法の利点は、中括弧内にプロパティを入れてオブジェクトを素早く作成出来ることにあります。 単純に「キー(key):値(value)」のペアを、カンマで区切ることでリストにすることが出来ます。 下記のコードは、"foo"、"age"、"baz"をキーとする3つプロパティを持つオブジェクトを作成します。 3つのキーの値は、それぞれ文字列の"bar"、数値の42、そして3つ目のプロパティはその値として別のオブジェクトを持ちます。

var object = {
  foo: "bar",
  age: 42,
  baz: { myProp: 12 },
}

プロパティへのアクセス

オブジェクトを作成すると、それらの読み込み、または変更をしたくなるかもしれません。 オブジェクトのプロパティは、ドット記法または角括弧記法を使用してアクセスすることが可能です。 詳細については、メンバ演算子を参照してください。

object.foo;     // "bar"
object["age"];  // 42

object.foo = "baz";

プロパティの定義

ここまでに、初期化子の文法を使用したプロパティの指定を学習しました。 よくあることですが、コード内の変数をオブジェクト内に置きたいといったケースがあります。 その場合、次のようなコードを目にするでしょう。

var a = "foo",
    b = 42,
    c = {};

var o = {
  a: a,
  b: b,
  c: c
};

ECMAScript 6では、より短い記法で同じことを実現出来ます。

var a = "foo",
    b = 42,
    c = {};

// プロパティ名の略記 (ES6)
var o = { a, b, c };

プロパティ名の重複

プロパティに同じ名前を使用すると、 2つ目のプロパティは、その1つ目のプロパティを上書きします。

var a = {x: 1, x: 2};
console.log(a); // { x: 2}

ECMAScript 5のstrictモードのコードでは、重複したプロパティ名はSyntaxError(文法エラー)とみなしていました。 ECMAScript 6では、算出プロパティ名(訳注: computed property - プロパティ名を処理によって決定する手法)を取り入れたことで、 実行時に重複が作成されてしまう可能性があるため、この制限は取り除かれました。

function haveES6DuplicatePropertySemantics(){
  "use strict";
  try {
    ({ prop: 1, prop: 2 });

    // strictモードで重複プロパティ名が許可されているため、
    // エラーはスローされません。
    return true;
  } catch (e) {
    // scrictモードで重複プロパティ名が禁止されているため、
    // エラーがスローされます。
    return false;
  }
}

メソッドの定義

オブジェクトのプロパティは、 関数(function)またはgettersetterのメソッドを参照することも可能です。

var o = {
  property: function ([parameters]) {},
  get property() {},
  set property(value) {},
};

ECMAScript 6では、略記記法が利用可能であるため、"function"のキーワードが不要になります。

// 略記メソッド名 (ES6)
var o = {
  property([parameters]) {},
  get property() {},
  set property(value) {},
  * generator() {}
};

より詳細な情報とメソッドの例については、メソッド定義を参照してください。

算出プロパティ名

ECMAScript 6からは、オブジェクト初期化子の文法は、算出プロパティ名をサポートします。 これは角括弧([])内に式を入れ、その処理によって算出した結果をプロパティ名とすることを可能にしてくれます。 これは、プロパティの読み込み・設定の際に既に使用されているプロパティへのアクセス文法の角括弧文法と、 釣り合いがとれたものになります。 そのため、オブジェクトのリテラル内部でも同様の文法を使用することが可能です。

// 算出プロパティ名 (ES6)
var i = 0;
var a = {
  ["foo" + ++i]: i,
  ["foo" + ++i]: i,
  ["foo" + ++i]: i
};

console.log(a.foo1); // 1
console.log(a.foo2); // 2
console.log(a.foo3); // 3

var param = 'size';
var config = {
  [param]: 12,
  ["mobile" + param.charAt(0).toUpperCase() + param.slice(1)]: 4
};

console.log(config); // { size: 12, mobileSize: 4 }

プロトタイプの変異

__proto__: valueまたは"__proto__": valueの形式によるプロパティの定義は、 __proto__という名前のプロパティを作成しません。 それどころか、もし与えた値がオブジェクトまたはnullの場合、 作成されたオブジェクトの[[Prototype]](プロトタイプ)をその値に変更します。 (もし、その値がオブジェクトまたはnullでなければ、そのオブジェクトは変更されません。)

var obj1 = {};
assert(Object.getPrototypeOf(obj1) === Object.prototype);

var obj2 = { __proto__: null };
assert(Object.getPrototypeOf(obj2) === null);     //prototypeを確認(nullにされている)

var protoObj = {};
var obj3 = { "__proto__": protoObj };
assert(Object.getPrototypeOf(obj3) === protoObj); //prototypeを確認(protoObjにされている)

var obj4 = { __proto__: "not an object or null" };
assert(Object.getPrototypeOf(obj4) === Object.prototype);
assert(!obj4.hasOwnProperty("__proto__"));  //自身の__proto__プロパティは存在しない

単一のプロトタイプ変異だけが、オブジェクトのリテラル内にあることを許可され、 複数のプロトタイプ変異は文法エラーになります。

コロン(:)記法を使用しないプロパティの定義は、プロトタイプ変異ではありません。 これらは、別の名前を使用して同様の定義で全く同じ挙動を行うプロパティの定義です。(翻訳に自信なし)

var __proto__ = "variable";

var obj1 = { __proto__ };
assert(Object.getPrototypeOf(obj1) === Object.prototype);
assert(obj1.hasOwnProperty("__proto__"));
assert(obj1.__proto__ === "variable");

var obj2 = { __proto__() { return "hello"; } };
assert(obj2.__proto__() === "hello");

var obj3 = { ["__prot" + "o__"]: 17 };
assert(obj3.__proto__ === 17);

オブジェクトリテラル - JSON

オブジェクトのリテラル記法は、JavaScript Object Notation (JSON)とは同じではありません。 ただし、これらはよく似ており、下記の点において違いがあります。

  • JSONは"property": value文法を使用したプロパティ定義のみを許可します。 プロパティ名はダブルクォーテーションにしなければならず、この定義を略記することは出来ません。
  • JSONの値は、文字列、数値、配列、true、false、nullまたは別の(JSON)オブジェクトのみが指定可能です。
  • 関数値(上述した"メソッド定義"を参照)は、JSONでは値として割り当てることは出来ません。
  • Dateのようなオブジェクトは、 JSON.parse()に文字列になります。
  • JSON.parse()は算出プロパティ名を拒否し、 エラーをスローします。

仕様

ブラウザ互換性

デスクトップ
機能 Chrome Firefox
(Gecko)
IE Opera Safari
基本 1 1.0 (1.7 or earlier) 1 1 1
算出プロパティ名 × 34 (34) × × ×
プロパティ名の略記 × 33 (33) × × ×
メソッド名の略記 × 34 (34) × × ×
モバイル
機能 Android Chrome for
Android
Firefox
Mobile
IE
Mobile
Opera
Mobile
Safari
Mobile
基本 1 1 1.0 (1.0) 1 1 1
算出プロパティ名 × × 34.0 (34) × × ×
プロパティ名の略記 × × 33.0 (33) × × ×
メソッド名の略記 × × 34.0 (34) × × ×

関連項目

 Back to top

© 2017 Mozilla Contributors
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.

このページは、ページトップのURL先のMozilla Developer Network(以下、MDN)のコンテンツを翻訳した内容を基に構成されています。 構成について異なる点も含まれますので、下記の項目を確認し、必要に応じて元のコンテンツをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。

  • 特定のブラウザに特化しすぎている情報やあまりにも古い情報、 または試験的に導入されているようなAPIや機能については、省略していることがあります。
  • 例やデモについて、実際にページ内で動作させる関係で一部ソースコードを変更している場合や、 その例で使用しているコンテンツの単語や文章などを日本人向けに変更しいてる場合があります。
  • MDNの更新頻度が高いため、元のコンテンツと比べ情報が古くなっている可能性があります。
  • "訳注:"などの断わりを入れた上で、日本人向けの情報の追記を行っている事があります。