--- title: オブジェクト初期化子 slug: Web/JavaScript/Reference/Operators/Object_initializer tags: - ECMAScript 2015 - JSON - JavaScript - Literal - Methods - Object - Primary Expression - computed - mutation - properties translation_of: Web/JavaScript/Reference/Operators/Object_initializer ---
オブジェクトは new Object()
、Object.create()
、リテラル表記法 (initializer 表記法) を使用して初期化されます。オブジェクト初期化子はオブジェクトのプロパティ名と関連した値のゼロ以上のペアのリストです。中括弧 ({}
) で囲まれます。
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) {}, };
これらの表記をサポートするための互換性の表を参照してください。非サポート環境では、これらの表記は、構文エラーにつながります。
// Shorthand property names (ES2015) var a = 'foo', b = 42, c = {}; var o = {a, b, c}; // Shorthand method names (ES2015) var o = { property(parameters) {} }; // Computed property names (ES2015) var prop = 'foo'; var o = { [prop]: 'hey', ['b' + 'ar']: 'there' };
オブジェクト初期化子は、{{jsxref("Object")}} の初期化を表す式です。オブジェクトはオブジェクトを表すプロパティで構成されます。オブジェクトプロパティの値は特定の {{Glossary("primitive")}} データ型か他のオブジェクトのどちらかを含みます。
プロパティを持たない空のオブジェクトは下記のように中括弧を記述することで生成されます。
var object = {};
リテラル表記法、initializer 表記法の利点は中括弧内にプロパティをもつオブジェクトをすばやく生成できる点です。また、カンマで区切られた key: value
のペアを記述することでプロパティ値の生成も可能です。以下に、三つのプロパティをもつオブジェクトを生成する方法を記します。キーは "foo"
、"age"
、"baz"
であり、各々のキーの値は、文字列の "bar"
、数値の 42
、そして baz
はオブジェクトがプロパティ値となります。
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 2015 では、同じことを達成するために利用可能な短い表記があります。:
var a = 'foo', b = 42, c = {}; // Shorthand property names (ES2015) var o = {a, b, c}; // In other words, console.log((o.a === {a}.a)); // true
プロパティに対して同じ名前を使用するとき、二番目のプロパティは最初のプロパティを上書きします。
var a = {x: 1, x: 2}; console.log(a); // {x: 2}
ECMAScript 5 の strict モードのコードでは、重複したプロパティの名前は {{jsxref("SyntaxError")}} とみなされます。実行時に重複を可能にする計算されたプロパティ名の導入により、ECMAScript 2015 ではこの制限は取り除かれました。
function haveES2015DuplicatePropertySemantics() { 'use strict'; try { ({prop: 1, prop: 2}); // No error thrown, duplicate property names allowed in strict mode return true; } catch (e) { // Error thrown, duplicates prohibited in strict mode return false; } }
オブジェクトのプロパティは function、getter メソッド、setter メソッドも参照することができます
var o = { property: function (parameters) {}, get property() {}, set property(value) {}, };
ECMAScript 2015 では、省略表記が利用可能です。そのため、キーワード "function" はもはや必要ではありません。
// Shorthand method names (ES2015) var o = { property(parameters) {}, *generator() {} };
ECMAScript 2015 では、その値がジェネレーター関数であるプロパティを簡潔に定義する方法があります。:
var o = { *generator() { ........... } };
ECMAScript 5 では、下記のように記述します (しかし、ES5 はジェネレーターを持たないことに注意してください):
var o = { generator: function* () { ........... } };
メソッドの詳細や例については、メソッド定義をご覧ください。
ECMAScript 2015 から、オブジェクト初期化子構文も計算されたプロパティ名をサポートします。括弧 []
の中に式を記述でき、それが計算されてプロパティ名として使用されます。これは、あなたが既にプロパティを読み込んだり設定したりするために使用したことがあるかもしれない、メンバー演算子構文のブラケット表記を思い起こさせます。今では、オブジェクトリテラルでも同様な構文を使うことができます:
// Computed property names (ES2015) 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}
ECMAScript proposal の Rest/Spread プロパティ (ステージ 4) オブジェクトリテラルにスプレッドプロパティを追加します。 渡されたオブジェクトから新しいオブジェクトに独自の列挙可能なプロパティをコピーします。
{{jsxref("Object.assign()")}} を使うよりも短いコードで prototype を除いた浅いコピーの作成や、マージしたオブジェクトの作成を書けます。
var obj1 = { foo: 'bar', x: 42 }; var obj2 = { foo: 'baz', y: 13 }; var clonedObj = { ...obj1 }; // Object { foo: "bar", x: 42 } var mergedObj = { ...obj1, ...obj2 }; // Object { foo: "baz", x: 42, y: 13 }
{{jsxref("Object.assign()")}} は setters をトリガーしますが、スプレッド構文はトリガーできません。
__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); var protoObj = {}; var obj3 = {'__proto__': protoObj}; assert(Object.getPrototypeOf(obj3) === protoObj); var obj4 = {__proto__: 'not an object or null'}; assert(Object.getPrototypeOf(obj4) === Object.prototype); assert(!obj4.hasOwnProperty('__proto__'));
単一のプロトタイプの変異のみ、オブジェクトリテラルに許可されています: すなわち、複数のプロトタイプの変異は構文エラーです。
"colon" 表記法を使用しないプロパティ定義はプロトタイプ変異ではありません。: 任意の他の名称を使用する同様の定義と同じように動作するプロパティ定義です。
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);
オブジェクトリテラル表記法は JavaScript Object Notation (JSON) とは異なります。それらは似ていますが、それらの間には違いがあります。:
"property": value
構文を使用するプロパティ定義のみ許可します。プロパティ名称は二重引用符で囲まなければなりません。そして、その定義は簡略にすることはできません。true
、false
、null
、別の (JSON) オブジェクトのみです。仕様 | ステータス | コメント |
---|---|---|
{{SpecName('ES1')}} | {{Spec2('ES1')}} | 初期定義。 |
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}} | {{Spec2('ES5.1')}} | getter と setter が追加されました。 |
{{SpecName('ES2015', '#sec-object-initializer', 'Object Initializer')}} | {{Spec2('ES2015')}} | 簡略表現メソッド/プロパティの名称と計算されたプロパティ名が追加されました。 |
{{SpecName('ESDraft', '#sec-object-initializer', 'Object Initializer')}} | {{Spec2('ESDraft')}} |
{{Compat("javascript.operators.object_initializer")}}