객체는 new Object()
, Object.create()
또는 literal 표기법 (initializer 표기법)을 사용하여 초기화될 수 있습니다. 객체 초기자(object initializer)는 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 2015의 새로운 표기법
이 표기법에 대한 지원은 호환성 표를 참조해 주세요. 비지원 환경에서, 이 표기법은 구문 오류로 이어집니다.
// 단축 속성명 (ES6) var a = "foo", b = 42, c = {}; var o = { a, b, c }; // 단축 메서드명 (ES6) var o = { property([parameters]) {}, get property() {}, set property(value) {}, * generator() {} }; // 속성 계산명 (ES6) var prop = "foo"; var o = { [prop]: "hey", ["b" + "ar"]: "there", };
설명
객체 초기자는 Object
의 초기화를 기술하는 식(expression)입니다. 객체는 속성으로 구성됩니다, 객체를 설명하는 데 사용되는. 객체의 속성값은 primitive 데이터 형 또는 다른 객체를 포함할 수 있습니다.
객체 생성
속성이 없는 빈 객체는 다음과 같이 만들 수 있습니다:
var object = {};
그러나, 리터럴(literal) 또는 초기자(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 = {}; // 단축 속성명 (ES6) var o = { a, b, c };
중복된 속성명
속성이 같은 이름을 쓰는 경우, 두 번째 속성은 첫 번째를 겹쳐씁니다.
var a = {x: 1, x: 2}; console.log(a); // {x: 2}
ECMAScript 5 엄격 모드 코드에서, 중복된 속성명은 SyntaxError
로 간주됐습니다. 런타임에 중복을 가능케 하는 속성 계산명 도입으로, ECMAScript 2015는 이 제한을 제거했습니다.
function haveES6DuplicatePropertySemantics(){ "use strict"; try { ({ prop: 1, prop: 2 }); // 오류 미 발생, 중복 속성명은 엄격 모드에서 허용됨 return true; } catch (e) { // 오류 발생, 중복은 엄격 모드에서 금지됨 return false; } }
메서드 정의
객체의 속성은 함수나 getter 또는 setter 메서드를 참조할 수도 있습니다.
var o = { property: function ([parameters]) {}, get property() {}, set property(value) {}, };
ECMAScript 2015에서는, 단축 표기법을 이용할 수 있습니다, 그래서 키워드 "function"은 더 이상 필요치 않습니다.
// 단축 메서드 명 (ES6) var o = { property([parameters]) {}, get property() {}, set property(value) {}, * generator() {} };
ECMAScript 2015에는 값이 생성기 함수인 속성을 간결하게 정의하는 법도 있습니다:
var o = { * generator() { ........... } };
ECMAScript 5에서는 다음과 같이 작성할 수 있습니다 (하지만 ES5는 생성기가 없음을 주의하세요):
var o = { generatorMethod: function *() { ........... } };
메서드에 관한 자세한 사항 및 예는, 메서드 정의 참조.
속성 계산명
ECMAScript 2015를 시작으로, 객체 초기자 구문은 속성 계산명(computed property name)도 지원합니다. 괄호 []
안에 식을 넣을 수 있고, 속성명으로 계산됩니다. 이는 속성 접근자 구문의 각괄호 표기법과 대칭이고, 당신은 이미 속성을 읽고 설정하는 데 사용했을 수 있습니다. 이제 당신은 객체 리터럴에서도 같은 구문을 쓸 수 있습니다:
// 속성 계산명 (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); 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__"));
단일 프로토타입 변이(mutation)만 객체 리터럴에 허용됩니다: 다중 프로토타입 변이는 구문 오류입니다.
"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에서 값은 오직 문자열, 숫자, 배열,
true
,false
,null
또는 다른 (JSON) 객체만 될 수 있습니다. - 함수 값(위 "메서드" 참조)은 JSON에서 값에 할당될 수 없습니다.
Date
같은 객체는JSON.parse()
후에 문자열이 됩니다.JSON.parse()
는 속성 계산명을 거부하고 오류가 발생됩니다.
스펙
스펙 | 상태 | 설명 |
---|---|---|
ECMAScript 1st Edition (ECMA-262) | Standard | 초기 정의. |
ECMAScript 5.1 (ECMA-262) The definition of 'Object Initializer' in that specification. |
Standard | getter 및 setter 추가됨. |
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Object Initializer' in that specification. |
Standard | 단축 메서드/속성 이름 및 속성 계산명 추가됨. |
ECMAScript 2017 Draft (ECMA-262) The definition of 'Object Initializer' in that specification. |
Draft |
브라우저 호환성
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | 1.0 | 1.0 (1.7 or earlier) | 1 | 1 | 1 |
Computed property names | (Yes) | 34 (34) | No support | No support | 7.1 |
Shorthand property names | (Yes) | 33 (33) | No support | No support | No support |
Shorthand method names | 42.0 | 34 (34) | No support | No support | No support |
Feature | Android | Android Webview | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile | Chrome for Android |
---|---|---|---|---|---|---|---|
Basic support | (Yes) | (Yes) | 1.0 (1.0) | 1 | 1 | 1 | 1.0 |
Computed property names | No support | (Yes) | 34.0 (34) | No support | No support | No support | No support |
Shorthand property names | No support | (Yes) | 33.0 (33) | No support | No support | No support | No support |
Shorthand method names | No support | 42.0 | 34.0 (34) | No support | No support | No support | 42.0 |