Skip to content

Commit f9aad69

Browse files
committed
[충돌해결 및 번역] Part1 7.1 프로퍼티 플래그와 설명자
1 parent 0a33fca commit f9aad69

1 file changed

Lines changed: 47 additions & 125 deletions

File tree

  • 1-js/07-object-properties/01-property-descriptors

1-js/07-object-properties/01-property-descriptors/article.md

Lines changed: 47 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
21
# 프로퍼티 플래그와 설명자
32

43
아시다시피 객체엔 프로퍼티가 저장됩니다.
54

6-
지금까진 프로퍼티를 단순히 '키-값' 쌍의 관점에서만 다뤘습니다. 그런데 사실 프로퍼티는 우리가 생각했던 것보다 더 유연하고 강력한 자료구조입니다.
5+
지금까진 프로퍼티를 단순히 '키-값' 쌍의 관점에서만 다뤘습니다. 그런데 사실 프로퍼티는 우리가 생각했던 것보다 더 유연하고 강력한 자료구조입니다.
76

87
이 챕터에선 객체 프로퍼티 추가 구성 옵션 몇 가지를 다루고, 이어지는 챕터에선 이 옵션들을 이용해 손쉽게 getter나 setter 함수를 만드는 법을 알아보겠습니다.
98

109
## 프로퍼티 플래그
1110

12-
객체 프로퍼티는 **`값(value)`** 과 함께 플래그(flag)라 불리는 특별한 속성 세 가지를 갖습니다.
11+
객체 프로퍼티는 **`값(value)`** 과 함께 플래그(flag)라 불리는 특별한 속성 세 가지를 갖습니다.
1312

1413
- **`writable`** -- `true`이면 값을 수정할 수 있습니다. 그렇지 않다면 읽기만 가능합니다.
1514
- **`enumerable`** -- `true`이면 반복문을 사용해 나열할 수 있습니다. 그렇지 않다면 반복문을 사용해 나열할 수 없습니다.
@@ -19,13 +18,10 @@
1918

2019
자 이제 본격적으로 프로퍼티 플래그에 대해 다뤄봅시다. 먼저 플래그를 얻는 방법을 알아보겠습니다.
2120

22-
<<<<<<< HEAD
23-
[Object.getOwnPropertyDescriptor](mdn:js/Object/getOwnPropertyDescriptor)메서드를 사용하면 특정 프로퍼티에 대한 정보를 *모두* 얻을 수 있습니다.
24-
=======
25-
The method [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor) allows to query the *full* information about a property.
26-
>>>>>>> upstream/master
21+
[Object.getOwnPropertyDescriptor](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor) 메서드를 사용하면 특정 프로퍼티에 대한 정보를 *모두* 얻을 수 있습니다.
2722

2823
문법:
24+
2925
```js
3026
let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
3127
```
@@ -42,12 +38,12 @@ let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
4238

4339
```js run
4440
let user = {
45-
name: "John"
41+
name: "John",
4642
};
4743

48-
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
44+
let descriptor = Object.getOwnPropertyDescriptor(user, "name");
4945

50-
alert( JSON.stringify(descriptor, null, 2 ) );
46+
alert(JSON.stringify(descriptor, null, 2));
5147
/* property descriptor:
5248
{
5349
"value": "John",
@@ -58,16 +54,12 @@ alert( JSON.stringify(descriptor, null, 2 ) );
5854
*/
5955
```
6056

61-
<<<<<<< HEAD
62-
메서드 [Object.defineProperty](mdn:js/Object/defineProperty)를 사용하면 플래그를 변경할 수 있습니다.
63-
=======
64-
To change the flags, we can use [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).
65-
>>>>>>> upstream/master
57+
메서드 [Object.defineProperty](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)를 사용하면 플래그를 변경할 수 있습니다.
6658

6759
문법:
6860

6961
```js
70-
Object.defineProperty(obj, propertyName, descriptor)
62+
Object.defineProperty(obj, propertyName, descriptor);
7163
```
7264

7365
`obj`, `propertyName`
@@ -76,7 +68,7 @@ Object.defineProperty(obj, propertyName, descriptor)
7668
`descriptor`
7769
: 적용하고자 하는 프로퍼티 설명자
7870

79-
`defineProperty`메서드는 객체에 해당 프로퍼티가 있으면 플래그를 원하는 대로 변경해줍니다. 프로퍼티가 없으면 인수로 넘겨받은 정보를 이용해 새로운 프로퍼티를 만듭니다. 이때 플래그 정보가 없으면 플래그 값은 자동으로 `false`가 됩니다.
71+
`defineProperty`메서드는 객체에 해당 프로퍼티가 있으면 플래그를 원하는 대로 변경해줍니다. 프로퍼티가 없으면 인수로 넘겨받은 정보를 이용해 새로운 프로퍼티를 만듭니다. 이때 플래그 정보가 없으면 플래그 값은 자동으로 `false`가 됩니다.
8072

8173
아래 예시를 보면 프로퍼티 `name`이 새로 만들어지고, 모든 플래그 값이 `false`가 된 것을 확인할 수 있습니다.
8274

@@ -128,13 +120,8 @@ user.name = "Pete"; // Error: Cannot assign to read only property 'name'
128120

129121
이제 `defineProperty`를 사용해 `writable` 플래그를 `true`로 변경하지 않는 한 그 누구도 객체의 이름을 변경할 수 없게 되었습니다.
130122

131-
<<<<<<< HEAD
132123
```smart header="에러는 엄격 모드에서만 발생합니다."
133-
비 엄격 모드에선 읽기 전용 프로퍼티에 값을 쓰려고 해도 에러가 발생하지 않습니다. 다만 이때 값을 변경하는 것은 불가능합니다. 비 엄격 모드에선 이와 같이 플래그에서 정한 규칙을 위반하는 행위는 에러 없이 그냥 무시됩니다.
134-
=======
135-
```smart header="Errors appear only in strict mode"
136-
In non-strict mode, no errors occur when writing to non-writable properties and such. But the operation still won't succeed. Flag-violating actions are just silently ignored in non-strict.
137-
>>>>>>> upstream/master
124+
비 엄격 모드에선 읽기 전용 프로퍼티에 값을 써도 에러가 발생하지 않습니다. 다만 이때 값을 변경하는 것은 불가능합니다. 비 엄격 모드에선 이와 같이 플래그에서 정한 규칙을 위반하는 행위는 에러 없이 그냥 무시됩니다.
138125
```
139126

140127
아래 예시는 위 예시와 동일하게 동작합니다. 다만 아래 예시에선 `defineProperty` 메서드를 사용해 프로퍼티를 밑바닥부터 만들어 보았습니다.
@@ -166,7 +153,7 @@ let user = {
166153
name: "John",
167154
toString() {
168155
return this.name;
169-
}
156+
},
170157
};
171158

172159
//커스텀 toString은 for...in을 사용해 열거할 수 있습니다.
@@ -205,18 +192,14 @@ alert(Object.keys(user)); // name
205192

206193
구성 가능하지 않음을 나타내는 플래그(non-configurable flag)인 `configurable:false`는 몇몇 내장 객체나 프로퍼티에 기본으로 설정되어있습니다.
207194

208-
<<<<<<< HEAD
209-
어떤 프로퍼티의 `configurable` 플래그가 `false`로 설정되어 있다면 해당 프로퍼티는 객체에서 지울 수 없습니다.
210-
=======
211-
A non-configurable property can't be deleted, its attributes can't be modified.
212-
>>>>>>> upstream/master
195+
어떤 프로퍼티의 `configurable` 플래그가 `false`로 설정되어 있다면 해당 프로퍼티는 객체에서 지울 수 없고, 플래그 값도 수정할 수 없습니다.
213196

214197
내장 객체 `Math``PI` 프로퍼티가 대표적인 예입니다. 이 프로퍼티는 쓰기와 열거, 구성이 불가능합니다.
215198

216199
```js run
217-
let descriptor = Object.getOwnPropertyDescriptor(Math, 'PI');
200+
let descriptor = Object.getOwnPropertyDescriptor(Math, "PI");
218201

219-
alert( JSON.stringify(descriptor, null, 2 ) );
202+
alert(JSON.stringify(descriptor, null, 2));
220203
/*
221204
{
222205
"value": 3.141592653589793,
@@ -226,6 +209,7 @@ alert( JSON.stringify(descriptor, null, 2 ) );
226209
}
227210
*/
228211
```
212+
229213
개발자가 코드를 사용해 `Math.PI` 값을 변경하거나 덮어쓰는 것도 불가능합니다.
230214

231215
```js run
@@ -234,102 +218,70 @@ Math.PI = 3; // Error, because it has writable: false
234218
// 수정도 불가능하지만 지우는 것 역시 불가능합니다.
235219
```
236220

237-
<<<<<<< HEAD
238-
`configurable` 플래그를 `false`로 설정하면 돌이킬 방법이 없습니다. `defineProperty`를 써도 값을 `true`로 되돌릴 수 없죠.
239-
240-
`configurable:false`가 만들어내는 구체적인 제약사항은 아래와 같습니다.
241-
1. `configurable` 플래그를 수정할 수 없음
242-
2. `enumerable` 플래그를 수정할 수 없음.
243-
3. `writable: false`의 값을 `true`로 바꿀 수 없음(`true``false`로 변경하는 것은 가능함).
244-
4. 접근자 프로퍼티 `get/set`을 변경할 수 없음(새롭게 만드는 것은 가능함).
245-
246-
이런 특징을 이용하면 아래와 같이 "영원히 변경할 수 없는" 프로퍼티(`user.name`)를 만들 수 있습니다.
247-
=======
248-
We also can't change `Math.PI` to be `writable` again:
249-
>>>>>>> upstream/master
221+
`Math.PI`를 다시 `writable`로 바꾸는 것도 불가능합니다.
250222

251223
```js run
252224
// Error, because of configurable: false
253225
Object.defineProperty(Math, "PI", { writable: true });
254226
```
255227

256-
There's absolutely nothing we can do with `Math.PI`.
228+
`Math.PI`로는 아무것도 할 수 없습니다.
257229

258-
Making a property non-configurable is a one-way road. We cannot change it back with `defineProperty`.
230+
`configurable` 플래그를 `false`로 설정하면 돌이킬 방법이 없습니다. `defineProperty`를 써도 값을 `true`로 되돌릴 수 없죠.
259231

260-
**Please note: `configurable: false` prevents changes of property flags and its deletion, while allowing to change its value.**
232+
**참고: `configurable: false`는 프로퍼티 플래그 변경과 삭제를 막지만, 값 변경은 허용합니다.**
261233

262-
Here `user.name` is non-configurable, but we can still change it (as it's writable):
234+
아래 예시에서 `user.name`은 구성 가능하지 않은 프로퍼티지만 writable이므로 값을 변경할 수 있습니다.
263235

264236
```js run
265237
let user = {
266-
name: "John"
238+
name: "John",
267239
};
268240

269241
Object.defineProperty(user, "name", {
270-
configurable: false
242+
configurable: false,
271243
});
272244

273-
user.name = "Pete"; // works fine
245+
user.name = "Pete"; // 정상 작동
274246
delete user.name; // Error
275247
```
276248

277-
And here we make `user.name` a "forever sealed" constant, just like the built-in `Math.PI`:
249+
아래 예시에서는 내장 객체 `Math.PI`처럼 `user.name`을 "변경할 수 없는" 상수로 만듭니다.
278250

279251
```js run
280252
let user = {
281-
name: "John"
253+
name: "John",
282254
};
283255

284256
Object.defineProperty(user, "name", {
285257
writable: false,
286-
configurable: false
258+
configurable: false,
287259
});
288260

289-
<<<<<<< HEAD
290-
*!*
291-
// user.name 프로퍼티의 값이나 플래그를 변경할 수 없습니다.
292-
// 아래와 같이 변경하려고 하면 에러가 발생합니다.
293-
// user.name = "Pete"
294-
// delete user.name
295-
// Object.defineProperty(user, "name", { value: "Pete" })
296-
Object.defineProperty(user, "name", {writable: true}); // Error
297-
*/!*
298-
```
299-
300-
```smart header="\"non-configurable\"\"non-writable\"과 다릅니다."
301-
`configurable` 플래그가 `false`이더라도 `writable` 플래그가 `true`이면 프로퍼티 값을 변경할 수 있습니다.
302-
303-
`configurable: false`는 플래그 값 변경이나 프로퍼티 삭제를 막기 위해 만들어졌지, 프로퍼티 값 변경을 막기 위해 만들어진 게 아닙니다.
304-
=======
305-
// won't be able to change user.name or its flags
306-
// all this won't work:
261+
// user.name과 플래그를 변경할 수 없습니다.
262+
// 아래는 모두 동작하지 않습니다.
307263
user.name = "Pete";
308264
delete user.name;
309265
Object.defineProperty(user, "name", { value: "Pete" });
310266
```
311267

312-
```smart header="The only attribute change possible: writable true -> false"
313-
There's a minor exception about changing flags.
268+
```smart header="가능한 플래그 변경: writable true -> false"
269+
플래그 변경에는 한 가지 예외가 있습니다.
270+
271+
구성 가능하지 않은 프로퍼티라도 `writable: true`를 `false`로 변경할 수 있습니다. 이렇게 하면 값 변경을 막을 수 있습니다. 반대로 false를 true로 변경하는 것은 불가능합니다.
314272
315-
We can change `writable: true` to `false` for a non-configurable property, thus preventing its value modification (to add another layer of protection). Not the other way around though.
316-
>>>>>>> upstream/master
317273
```
318274

319275
## Object.defineProperties
320276

321-
<<<<<<< HEAD
322-
[Object.defineProperties(obj, descriptors)](mdn:js/Object/defineProperties) 메서드를 사용하면 프로퍼티 여러 개를 한 번에 정의할 수 있습니다.
323-
=======
324-
There's a method [Object.defineProperties(obj, descriptors)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties) that allows to define many properties at once.
325-
>>>>>>> upstream/master
277+
[Object.defineProperties(obj, descriptors)](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties) 메서드를 사용하면 프로퍼티 여러 개를 한 번에 정의할 수 있습니다.
326278

327279
문법:
328280

329281
```js
330282
Object.defineProperties(obj, {
331283
prop1: descriptor1,
332-
prop2: descriptor2
284+
prop2: descriptor2,
333285
// ...
334286
});
335287
```
@@ -348,11 +300,7 @@ Object.defineProperties(user, {
348300

349301
## Object.getOwnPropertyDescriptors
350302

351-
<<<<<<< HEAD
352-
[Object.getOwnPropertyDescriptors(obj)](mdn:js/Object/getOwnPropertyDescriptors) 메서드를 사용하면 프로퍼티 설명자를 전부 한꺼번에 가져올 수 있습니다.
353-
=======
354-
To get all property descriptors at once, we can use the method [Object.getOwnPropertyDescriptors(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors).
355-
>>>>>>> upstream/master
303+
[Object.getOwnPropertyDescriptors(obj)](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors) 메서드를 사용하면 프로퍼티 설명자를 한꺼번에 가져올 수 있습니다.
356304

357305
이 메서드를 `Object.defineProperties`와 함께 사용하면 객체 복사 시 플래그도 함께 복사할 수 있습니다.
358306

@@ -364,64 +312,38 @@ let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));
364312

365313
```js
366314
for (let key in user) {
367-
clone[key] = user[key]
315+
clone[key] = user[key];
368316
}
369317
```
370318

371-
그런데 이 방법은 플래그는 복사하지 않습니다. 플래그 정보도 복사하려면 `Object.defineProperties`사용하시기 바랍니다.
319+
그런데 이 방법은 플래그를 복사하지 않습니다. 플래그 정보도 복사하려면 `Object.defineProperties`사용하기 바랍니다.
372320

373-
<<<<<<< HEAD
374-
위 샘플 코드처럼 `for..in`을 사용해 객체를 복사하면 심볼형 프로퍼티도 놓치게 됩니다. 하지만 `Object.getOwnPropertyDescriptors`는 심볼형 프로퍼티를 포함한 프로퍼티 설명자 *전체*를 반환합니다.
375-
=======
376-
Another difference is that `for..in` ignores symbolic and non-enumerable properties, but `Object.getOwnPropertyDescriptors` returns *all* property descriptors including symbolic and non-enumerable ones.
377-
>>>>>>> upstream/master
321+
또 다른 점은 `for..in`은 심볼형 프로퍼티와 열거가 불가능한 프로퍼티를 무시합니다. 하지만 `Object.getOwnPropertyDescriptors`는 심볼형 프로퍼티와 열거가 불가능한 프로퍼티를 포함한 프로퍼티 설명자 *전체*를 반환합니다.
378322

379323
## 객체 수정을 막아주는 다양한 메서드
380324

381325
프로퍼티 설명자는 특정 프로퍼티 하나를 대상으로 합니다.
382326

383327
아래 메서드를 사용하면 한 객체 내 프로퍼티 *전체*를 대상으로 하는 제약사항을 만들 수 있습니다.
384328

385-
<<<<<<< HEAD
386-
[Object.preventExtensions(obj)](mdn:js/Object/preventExtensions)
329+
[Object.preventExtensions(obj)](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions)
387330
: 객체에 새로운 프로퍼티를 추가할 수 없게 합니다.
388331

389-
[Object.seal(obj)](mdn:js/Object/seal)
390-
: 새로운 프로퍼티 추가나 기존 프로퍼티 삭제를 막아줍니다. 프로퍼티 전체에 `configurable: false`를 설정하는 것과 동일한 효과입니다.
391-
392-
[Object.freeze(obj)](mdn:js/Object/freeze)
393-
: 새로운 프로퍼티 추가나 기존 프로퍼티 삭제, 수정을 막아줍니다. 프로퍼티 전체에 `configurable: false, writable: false`를 설정하는 것과 동일한 효과입니다.
394-
=======
395-
[Object.preventExtensions(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions)
396-
: Forbids the addition of new properties to the object.
332+
[Object.seal(obj)](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/seal)
333+
: 새로운 프로퍼티 추가나 기존 프로퍼티 삭제를 막아줍니다. 기존 프로퍼티 전체에 `configurable: false`를 설정합니다.
397334

398-
[Object.seal(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal)
399-
: Forbids adding/removing of properties. Sets `configurable: false` for all existing properties.
400-
401-
[Object.freeze(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
402-
: Forbids adding/removing/changing of properties. Sets `configurable: false, writable: false` for all existing properties.
403-
>>>>>>> upstream/master
335+
[Object.freeze(obj)](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
336+
: 새로운 프로퍼티 추가나 기존 프로퍼티 삭제, 수정을 막아줍니다. 기존 프로퍼티 전체에 `configurable: false, writable: false`를 설정합니다.
404337

405338
아래 메서드는 위 세 가지 메서드를 사용해서 설정한 제약사항을 확인할 때 사용할 수 있습니다.
406339

407-
<<<<<<< HEAD
408-
[Object.isExtensible(obj)](mdn:js/Object/isExtensible)
340+
[Object.isExtensible(obj)](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible)
409341
: 새로운 프로퍼티를 추가하는 게 불가능한 경우 `false`를, 그렇지 않은 경우 `true`를 반환합니다.
410342

411-
[Object.isSealed(obj)](mdn:js/Object/isSealed)
343+
[Object.isSealed(obj)](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed)
412344
: 프로퍼티 추가, 삭제가 불가능하고 모든 프로퍼티가 `configurable: false`이면 `true`를 반환합니다.
413345

414-
[Object.isFrozen(obj)](mdn:js/Object/isFrozen)
346+
[Object.isFrozen(obj)](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen)
415347
: 프로퍼티 추가, 삭제, 변경이 불가능하고 모든 프로퍼티가 `configurable: false, writable: false`이면 `true`를 반환합니다.
416-
=======
417-
[Object.isExtensible(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible)
418-
: Returns `false` if adding properties is forbidden, otherwise `true`.
419-
420-
[Object.isSealed(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed)
421-
: Returns `true` if adding/removing properties is forbidden, and all existing properties have `configurable: false`.
422-
423-
[Object.isFrozen(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen)
424-
: Returns `true` if adding/removing/changing properties is forbidden, and all current properties are `configurable: false, writable: false`.
425-
>>>>>>> upstream/master
426348

427349
위 메서드들은 실무에선 잘 사용되지 않습니다.

0 commit comments

Comments
 (0)