aboutsummaryrefslogtreecommitdiff
path: root/files/ko/web/javascript/reference/operators/object_initializer/index.md
blob: b4b6eb6bd994fe0a40b7787fa8147298067559f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
---
title: 객체 초기자
slug: Web/JavaScript/Reference/Operators/Object_initializer
tags:
  - ECMAScript 2015
  - JSON
  - JavaScript
  - Language feature
  - Literal
  - Methods
  - Object
  - Primary Expression
  - computed
  - mutation
  - properties
browser-compat: javascript.operators.object_initializer
---
{{JsSidebar("Operators")}}

객체는 [`new Object()`](/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/Object), [`Object.create()`](/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/create) 또는 _literal_ 표기법(_initializer_ 표기법)을 사용해 초기화될 수 있습니다. 객체 초기자는 중괄호(`{}`)로 묶인 0개 이상의 객체의 프로퍼티명과 관련 값의 쌍을 콤마로 구분한 목록입니다.

{{EmbedInteractiveExample("pages/js/expressions-objectinitializer.html", "taller")}}

## 구문

```js
let o = {}
let o = {a: 'foo', b: 42, c: {}}

let a = 'foo', b = 42, c = {}
let o = {a: a, b: b, c: c}

let o = {
  property: function (parameters) {},
  get property() {},
  set property(value) {}
};
```

### ECMAScript 2015의 새로운 표기법

이러한 표기법의 지원에 대해서는 호환성 테이블을 확인해주세요. 지원하지 않는 환경에서는 이러한 표기법들은 구문 에러를 유발합니다.

```js
// 프로퍼티명 약식 (ES2015)
let a = 'foo', b = 42, c = {};
let o = {a, b, c}

// 프로퍼티명 약식 (ES2015)
let o = {
  property(parameters) {}
}

// 계산된 프로퍼티명 (ES2015)
let prop = 'foo';
let o = {
  [prop]: 'hey',
  ['b' + 'ar']: 'there'
}
```

## 설명

객체 초기자는 {{jsxref("Object")}}의 초기화를 나타내는 표현입니다. 객체는 객체를 나타내는 데 사용되는 _properties_로 구성됩니다. 객체 프로퍼티의 값은 [원시 값](/ko/docs/Glossary/Primitive) 데이터 타입 또는 다른 객체를 포함할 수 있습니다.

### 객체 리터럴 표기법 vs JSON

객체 리터럴 표기법은 **J**ava**S**cript **O**bject **N**otation([JSON](/ko/docs/Glossary/JSON))과 동일하지 않습니다. 비슷하게 보이지만 다음과 같은 차이가 있습니다.

- JSON은 _오직_ `"property": value` 구문을 사용해 정의한 프로퍼티만 허용합니다. 프로퍼티명에는 반드시 큰따옴표를 사용해야 하며 약식으로 정의할 수 없습니다.
- JSON에서 값은 문자열, 숫자, 배열, `true`, `false`, `null`, 또는 다른 (JSON) 객체만 사용할 수 있습니다.
- 함수 값(아래 "메서드"를 보세요)은 JSON의 값으로 할당할 수 없습니다.
- {{jsxref("Date")}}와 같은 객체는 {{jsxref("JSON.parse()")}} 이후의 문자열이 됩니다.
- {{jsxref("JSON.parse()")}}는 계산된 프로퍼티명을 거부하며 에러가 발생합니다.

## 예제

### 객체 생성하기

프로퍼티가 없는 빈 객체는 다음과 같이 생성합니다.

```js
let object = {}
```

_literal_ 또는 _initializer_ 표기법의 장점은 중괄호 안에 프로퍼티를 갖는 객체를 빠르게 생성할 수 있다는 것입니다. 콤마로 구분하여 `key: value` 상의 목록을 작성하면 됩니다.

다음 코드는 세 개의 프로퍼티를 갖는 객체를 생성하며 키는 `"foo"`, `"age"`, `"baz"`입니다. 다음 세 키의 값은 문자열 `"bar"`, 숫자 `42`, 그리고 다른 객체입니다.

```js
let object = {
  foo: 'bar',
  age: 42,
  baz: {myProp: 12}
}
```

### 프로퍼티에 접근하기

객체를 생성한 후에는 이를 읽거나 변경할 수 있습니다. 객체 프로퍼티는 점 표기법 또는 대괄호 표기법을 사용해 접근할 수 있습니다(자세한 정보는 [프로퍼티 접근자](/ko/docs/Web/JavaScript/Reference/Operators/Property_Accessors)를 보세요).

```js
object.foo // "bar"
object['age'] // 42
object.baz          // {myProp: 12}
object.baz.myProp   //12
```

### 프로퍼티 정의

우리는 초기자 구문을 사용해 프로퍼티를 작성하는 방법을 이미 배웠습니다. 때때로 코드의 변수를 객체로 넣고 싶은 경우가 있습니다. 다음과 같은 코드를 보게 될 수 있습니다.

```js
let a = 'foo',
    b = 42,
    c = {};

let o = {
  a: a,
  b: b,
  c: c
}
```

ECMAScript 2015를 사용하면 더 짧은 표기법을 사용해 동일한 결과를 얻을 수 있습니다.

```js
let a = 'foo',
    b = 42,
    c = {};

// 프로퍼티명 약식 (ES2015)
let o = {a, b, c}

// 다르게 작성하면,
console.log((o.a === {a}.a)) // true
```

#### 중복된 프로퍼티명

동일한 프로퍼티명을 사용하면 두 번째 프로퍼티가 첫 번째 프로퍼티를 덮어씁니다.

```js
let a = {x: 1, x: 2}
console.log(a) // {x: 2}
```

ECMAScript 5 엄격 모드 코드에서는 중복된 프로퍼티명을 {{jsxref("SyntaxError")}}로 간주합니다. 런타임 시 복제를 가능하게 한 계산된 프로퍼티 명의 도입으로 ECMScript 2015는 이 제한을 제거했습니다.

```js
function haveES2015DuplicatePropertySemantics() {
  'use strict';
  try {
    ({prop: 1, prop: 2});

    // 에러가 발생하지 않음, 중복된 프로퍼티명이 엄격 모드에서 허용됨
    return true;
  } catch(e) {
    // 에러가 발생함, 엄격 모드에서 중복이 금지됨
    return false;
  }
}
```

### 메서드 정의

객체의 프로퍼티는 [function](/ko/docs/Web/JavaScript/Reference/Functions) 또는 [getter](/ko/docs/Web/JavaScript/Reference/Functions/get) 또는 [setter](/ko/docs/Web/JavaScript/Reference/Functions/set) 메서드를 참조할 수도 있습니다.

```js
let o = {
  property: function (parameters) {},
  get property() {},
  set property(value) {}
}
```

ECMAScript 2015에서는 약식 표기법을 사용할 수 있으므로 "`function`" 키워드는 필요하지 않습니다.

```js
// 약식 메서드명(ES2015)
let o = {
  property(parameters) {},
}
```

ECMAScript 2015에서는 값이 generator 함수인 프로퍼티를 간결하게 정의하는 방법이 있습니다.

```js
let o = {
  *generator() {
    ...........
  }
};
```

다음의 ES5와 유사한 표기법과 동일합니다(하지만 ECMAScript 5에는 generator가 없음을 유의하세요).

```js
let o = {
  generator: function* () {
    ...........
  }
};
```

메서드에 대한 상세 정보와 예제는 [메서드 정의](/ko/docs/Web/JavaScript/Reference/Functions/Method_definitions)를 보세요.

### 계산된 프로퍼티명

ECMAScript 2015부터 객체 초기자 구문은 계산된 프로퍼티 명도 지원합니다. 대괄호 `[]` 안에서 표현식을 허용하며, 표현식은 프로퍼티명으로 계산되어 사용됩니다. 이는 이미 프로퍼티를 읽고 설정하는 데 사용하는 [프로퍼티 접근자](/ko/docs/Web/JavaScript/Reference/Operators/Property_Accessors) 구문의 대괄호 표기법을 연상시킵니다.

이제 객체 리터럴에서도 유사한 구문을 사용할 수 있습니다.

```js
// 계산된 프로퍼티명(ES2015)
let i = 0
let 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

const items = ["A","B","C"];
const obj = {
[items]: "Hello"
}
console.log(obj); // A,B,C: "Hello"
console.log(obj["A,B,C"]) // "Hello"

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

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

### 전개 프로퍼티

[ECMAScript의 나머지/전개 프로퍼티](https://github.com/tc39/proposal-object-rest-spread) 제안(stage 4)은 객체 리터럴에 [전개](/ko/docs/Web/JavaScript/Reference/Operators/Spread_syntax) 프로퍼티를 추가합니다. 이는 제공된 객체로부터 새로운 객체로 자신만의 열거형 프로퍼티를 복사합니다.

이제 {{jsxref("Object.assign()")}} 보다 더 짧은 구문을 사용해 얕은 복제(`prototype` 제외) 또는 객체 병합이 가능합니다.

```js
let obj1 = { foo: 'bar', x: 42 }
let obj2 = { foo: 'baz', y: 13 }

let clonedObj = { ...obj1 }
// Object { foo: "bar", x: 42 }

let mergedObj = { ...obj1, ...obj2 }
// Object { foo: "baz", x: 42, y: 13 }
```

> **경고:** {{jsxref("Object.assign()")}}은 [setters](/ko/docs/Web/JavaScript/Reference/Functions/set)를 트리거하는 반면 전개 연산자는 그렇지 않음을 유의하세요!

### 프로토타입 변형

`__proto__: value` 또는 `"__proto__": value` 형태의 프로토타입 정의는 `__proto__` 이름을 갖는 프로퍼티를 생성하지 않습니다. 대신에, 제공된 값이 객체 또는 [`null`](/ko/docs/Web/JavaScript/Reference/Global_Objects/null)인 경우, 생성된 객체의 `[[Prototype]]`을 해당 값으로 변경합니다(값이 객체 또는 `null`이 아닌 경우, 객체는 변경되지 않습니다).

```js
let obj1 = {}
assert(Object.getPrototypeOf(obj1) === Object.prototype)

let obj2 = {__proto__: null}
assert(Object.getPrototypeOf(obj2) === null)

let protoObj = {}
let obj3 = {'__proto__': protoObj}
assert(Object.getPrototypeOf(obj3) === protoObj)

let obj4 = {__proto__: 'not an object or null'}
assert(Object.getPrototypeOf(obj4) === Object.prototype)
assert(!obj4.hasOwnProperty('__proto__'))
```

객체 리터럴에서는 단일 프로토타입 변형만 허용됩니다. 다중 프로토타입 변형은 구문 에러입니다.

"콜론" 표기법을 사용하지 않는 프로퍼티 정의는 프로토타입 변형이 아닙니다. 이는 다른 이름을 사용하여 유사한 정의와 동일하게 동작하는 프로퍼티 정의입니다.

```js
let __proto__ = 'variable'

let obj1 = {__proto__}
assert(Object.getPrototypeOf(obj1) === Object.prototype)
assert(obj1.hasOwnProperty('__proto__'))
assert(obj1.__proto__ === 'variable')

let obj2 = {__proto__() { return 'hello'; }}
assert(obj2.__proto__() === 'hello')

let obj3 = {['__prot' + 'o__']: 17}
assert(obj3.__proto__ === 17)
```

## 명세

{{Specifications}}

## 브라우저 호환성

{{Compat}}

## 같이 보기

- [프로퍼티 접근자](/ko/docs/Web/JavaScript/Reference/Operators/Property_Accessors)
- [`get`](/ko/docs/Web/JavaScript/Reference/Functions/get) / [`set`](/ko/docs/Web/JavaScript/Reference/Functions/set)
- [메서드 정의](/ko/docs/Web/JavaScript/Reference/Functions/Method_definitions)
- [Lexical grammar](/ko/docs/Web/JavaScript/Reference/Lexical_grammar)