オブジェクトは 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) {},
};
ECMAScript 2015 での新しい表記法
これらの表記をサポートするための互換性の表を参照してください。非サポート環境では、これらの表記は、構文エラーにつながります。
// 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'
};
説明
オブジェクト初期化子は、Object の初期化を表す式です。オブジェクトはオブジェクトを表すプロパティで構成されます。オブジェクトプロパティの値は特定の primitive データ型か他のオブジェクトのどちらかを含みます。
オブジェクトの生成
プロパティを持たない空のオブジェクトは下記のように生成されます。:
var object = {};
しかしながら、リテラル表記法か initializer 表記法の利点は中括弧内にプロパティをもつオブジェクトをすばやく生成できる点です。単にキーのリストを記譜します。: カンマで区切られた値のペアです。次のコードでは、三つのプロパティをもつオブジェクトを生成します。そして、そのキーは "foo"、"age"、"baz" です。これらのキーの値は、文字列の "bar"、数値の 42、そして、三番目のプロパティは値として別のオブジェクトを持ちます。
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 モードのコードでは、重複したプロパティの名前は 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 = {
generatorMethod: 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 }
プロトタイプ変異
__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);
オブジェクトリテラル表記法 vs JSON
オブジェクトリテラル表記法は JavaScript Object Notation (JSON) とは異なります。それらは似ていますが、そられの間には違いがあります。:
- JSON は、
"property": value構文を使用するプロパティ定義のみ許可します。プロパティ名称は二重引用符で囲まなければなりません。そして、その定義は簡略にすることはできません。 - JSON ではその値は strings、numbers、arrays、
true、false、null、別の (JSON) オブジェクトのみです。 - 関数の値 (上記"メソッド"を参照) は JSON では値を割り当てることができません。
DateのようなオブジェクトはJSON.parse()の後で string になります。JSON.parse()は計算されたプロパティ名を拒否し、エラーがスローされます。
仕様
| 仕様 | ステータス | コメント |
|---|---|---|
| ECMAScript 1st Edition (ECMA-262) | 標準 | 初期定義。 |
| ECMAScript 5.1 (ECMA-262) Object Initializer の定義 |
標準 | getter と setter が追加されました。 |
| ECMAScript 2015 (6th Edition, ECMA-262) Object Initializer の定義 |
標準 | 簡略表現メソッド/プロパティの名称と計算されたプロパティ名が追加されました。 |
| ECMAScript Latest Draft (ECMA-262) Object Initializer の定義 |
ドラフト |
ブラウザー実装状況
| 機能 | Chrome | Edge | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|---|
| 基本サポート | 1.0 | (有) | 1.0 (1.7 or earlier) | 1 | 1 | 1 |
| 計算されたプロパティ名 | (有) | (有) | 34 (34) | 未サポート | 34 | 7.1 |
| 簡略表現プロパティ名 | (有) | (有) | 33 (33) | 未サポート | 34 | 9 |
| 簡略表現メソッド名 | 42.0 | (有) | 34 (34) | 未サポート | 34 | 9 |
| 機能 | Android | Android Webview | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile | Chrome for Android |
|---|---|---|---|---|---|---|---|
| 基本サポート | (有) | (有) | 1.0 (1.0) | 1 | 1 | 1 | 1.0 |
| 計算されたプロパティ名 | 未サポート | (有) | 34.0 (34) | 未サポート | 34 | 7.1 | 未サポート |
| 簡略表現プロパティ名 | 未サポート | (有) | 33.0 (33) | 未サポート | 34 | 9 | 未サポート |
| 簡略表現メソッド名 | 未サポート | 42.0 | 34.0 (34) | 未サポート | 34 | 9 | 42.0 |