You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/04-object-basics/08-symbol/article.md
+11-78Lines changed: 11 additions & 78 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,22 +1,18 @@
1
1
2
2
# 심볼형
3
3
4
-
<<<<<<< HEAD
5
4
자바스크립트는 객체 프로퍼티 키로 오직 문자형과 심볼형만을 허용합니다. 숫자형, 불린형 모두 불가능하고 오직 문자형과 심볼형만 가능하죠.
6
5
7
6
지금까지는 프로퍼티 키가 문자형인 경우만 살펴보았습니다. 이번 챕터에선 프로퍼티 키로 심볼값을 사용해 보면서, 심볼형 키를 사용할 때의 이점에 대해 살펴보도록 하겠습니다.
8
-
=======
9
-
By specification, only two primitive types may serve as object property keys:
10
7
11
-
-string type, or
12
-
-symbol type.
8
+
-문자형 또는
9
+
-심볼형
13
10
14
-
Otherwise, if one uses another type, such as number, it's autoconverted to string. So that `obj[1]` is the same as `obj["1"]`, and `obj[true]` is the same as `obj["true"]`.
11
+
숫자형 등 다른 자료형을 키로 사용하면 문자형으로 자동 변환됩니다. 따라서 `obj[1]`은 `obj["1"]`과 같고, `obj[true]`는 `obj["true"]`와 같습니다.
15
12
16
-
Until now we've been using only strings.
13
+
지금까지는 프로퍼티 키가 문자형인 경우만 살펴보았습니다.
17
14
18
-
Now let's explore symbols, see what they can do for us.
19
-
>>>>>>> upstream/master
15
+
이제 심볼에 대해 알아보면서 심볼형 키를 사용할 때의 이점에 대해 살펴보겠습니다.
20
16
21
17
## 심볼
22
18
@@ -25,29 +21,18 @@ Now let's explore symbols, see what they can do for us.
25
21
`Symbol()`을 사용하면 심볼값을 만들 수 있습니다.
26
22
27
23
```js
28
-
<<<<<<<HEAD
29
24
// id는 새로운 심볼이 됩니다.
30
25
let id =Symbol();
31
26
```
32
27
33
28
심볼을 만들 때 심볼 이름이라 불리는 설명을 붙일 수도 있습니다. 심볼 이름은 디버깅 시 아주 유용합니다.
34
-
=======
35
-
let id = Symbol();
36
-
```
37
-
38
-
Upon creation, we can give symbols a description (also called a symbol name), mostly useful for debugging purposes:
39
-
>>>>>>> upstream/master
40
29
41
30
```js
42
31
// 심볼 id에는 "id"라는 설명이 붙습니다.
43
32
let id =Symbol("id");
44
33
```
45
34
46
-
<<<<<<< HEAD
47
35
심볼은 유일성이 보장되는 자료형이기 때문에, 설명이 동일한 심볼을 여러 개 만들어도 각 심볼값은 다릅니다. 심볼에 붙이는 설명(심볼 이름)은 어떤 것에도 영향을 주지 않는 이름표 역할만을 합니다.
48
-
=======
49
-
Symbols are guaranteed to be unique. Even if we create many symbols with exactly the same description, they are different values. The description is just a label that doesn't affect anything.
50
-
>>>>>>> upstream/master
51
36
52
37
설명이 같은 심볼 두 개를 만들고 이를 비교해보겠습니다. 동일 연산자(`==`)로 비교 시 `false`가 반환되는 것을 확인할 수 있습니다.
53
38
@@ -62,15 +47,10 @@ alert(id1 == id2); // false
62
47
63
48
참고로 Ruby 등의 언어에서도 '심볼'과 유사한 개념을 사용하는데, 자바스크립트의 심볼은 이들 언어에 쓰이는 심볼과는 다르기 때문에 혼동하지 마시길 바랍니다.
64
49
65
-
<<<<<<< HEAD
50
+
요약하자면, 심볼은 이름(설명)을 선택적으로 붙일 수 있는 "유일무이한 원시값"입니다. 이제 심볼을 어디에 사용할 수 있는지 살펴봅시다.
51
+
66
52
````warn header="심볼은 문자형으로 자동 형 변환되지 않습니다."
67
53
자바스크립트에선 문자형으로의 암시적 형 변환이 비교적 자유롭게 일어나는 편입니다. `alert` 함수가 거의 모든 값을 인자로 받을 수 있는 이유가 이 때문이죠. 그러나 심볼은 예외입니다. 심볼형 값은 다른 자료형으로 암시적 형 변환(자동 형 변환)되지 않습니다.
68
-
=======
69
-
So, to summarize, a symbol is a "primitive unique value" with an optional description. Let's see where we can use them.
70
-
71
-
````warn header="Symbols don't auto-convert to a string"
72
-
Most values in JavaScript support implicit conversion to a string. For instance, we can `alert` almost any value, and it will work. Symbols are special. They don't auto-convert.
73
-
>>>>>>> upstream/master
74
54
75
55
아래 예시에서 `alert`는 에러를 발생시킵니다.
76
56
@@ -83,25 +63,15 @@ alert(id); // TypeError: Cannot convert a Symbol value to a string
83
63
84
64
문자열과 심볼은 근본이 다르기 때문에 우연히라도 서로의 타입으로 변환돼선 안 됩니다. 자바스크립트에선 '언어 차원의 보호장치(language guard)'를 마련해 심볼형이 다른 형으로 변환되지 않게 막아줍니다.
85
65
86
-
<<<<<<< HEAD
87
66
심볼을 반드시 출력해줘야 하는 상황이라면 아래와 같이 `.toString()` 메서드를 명시적으로 호출해주면 됩니다.
88
-
=======
89
-
If we really want to show a symbol, we need to explicitly call `.toString()` on it, like here:
90
-
91
-
>>>>>>> upstream/master
92
67
```js run
93
68
let id = Symbol("id");
94
69
*!*
95
70
alert(id.toString()); // Symbol(id)가 얼럿 창에 출력됨
96
71
*/!*
97
72
```
98
73
99
-
<<<<<<< HEAD
100
74
`symbol.description` 프로퍼티를 이용하면 설명만 보여주는 것도 가능합니다.
101
-
=======
102
-
Or get `symbol.description` property to show the description only:
103
-
104
-
>>>>>>> upstream/master
105
75
```js run
106
76
let id = Symbol("id");
107
77
*!*
@@ -113,12 +83,7 @@ alert(id.description); // id
113
83
114
84
## '숨김' 프로퍼티
115
85
116
-
<<<<<<< HEAD
117
-
심볼을 이용하면 '숨김(hidden)' 프로퍼티를 만들 수 있습니다. 숨김 프로퍼티는 외부 코드에서 접근이 불가능하고 값도 덮어쓸 수 없는 프로퍼티입니다.
118
-
=======
119
-
120
-
Symbols allow us to create "hidden" properties of an object, that no other part of code can accidentally access or overwrite.
121
-
>>>>>>> upstream/master
86
+
심볼을 이용하면 "숨김(hidden)" 프로퍼티를 만들 수 있습니다. 숨김 프로퍼티는 외부 코드에서 접근이 불가능하고 값도 덮어쓸 수 없는 프로퍼티입니다.
122
87
123
88
서드파티 코드에서 가지고 온 `user`라는 객체가 여러 개 있고, `user`를 이용해 어떤 작업을 해야 하는 상황이라고 가정해 봅시다. `user`에 식별자를 붙여주도록 합시다.
124
89
@@ -138,15 +103,11 @@ alert( user[id] ); // 심볼을 키로 사용해 데이터에 접근할 수 있
138
103
139
104
그런데 문자열 `"id"`를 키로 사용해도 되는데 `Symbol("id")`을 사용한 이유가 무엇일까요?
140
105
141
-
<<<<<<< HEAD
142
106
`user`는 서드파티 코드에서 가지고 온 객체이므로 함부로 새로운 프로퍼티를 추가할 수 없습니다. 그런데 심볼은 서드파티 코드에서 접근할 수 없기 때문에, 심볼을 사용하면 서드파티 코드가 모르게 `user`에 식별자를 부여할 수 있습니다.
143
107
144
108
상황 하나를 더 가정해보겠습니다. 제3의 스크립트(자바스크립트 라이브러리 등)에서 `user`를 식별해야 하는 상황이 벌어졌다고 해보죠. `user`의 원천인 서드파티 코드, 현재 작성 중인 스크립트, 제3의 스크립트가 각자 서로의 코드도 모른 채 `user`를 식별해야 하는 상황이 벌어졌습니다.
145
-
=======
146
-
As `user` objects belong to another codebase, it's unsafe to add fields to them, since we might affect pre-defined behavior in that other codebase. However, symbols cannot be accessed accidentally. The third-party code won't be aware of newly defined symbols, so it's safe to add symbols to the `user` objects.
147
109
148
-
Also, imagine that another script wants to have its own identifier inside `user`, for its own purposes.
149
-
>>>>>>> upstream/master
110
+
또한, 또 다른 스크립트가 자기만의 목적을 위해 `user` 안에 자체 식별자를 추가해야 하는 상황을 가정해 봅시다.
150
111
151
112
제3의 스크립트에선 아래와 같이 `Symbol("id")`을 이용해 전용 식별자를 만들어 사용할 수 있습니다.
152
113
@@ -209,19 +170,13 @@ let user = {
209
170
for (let key in user) alert(key); // name과 age만 출력되고, 심볼은 출력되지 않습니다.
210
171
*/!*
211
172
212
-
<<<<<<<HEAD
213
173
// 심볼로 직접 접근하면 잘 작동합니다.
214
174
alert( "직접 접근한 값: "+ user[id] );
215
175
```
216
176
217
-
`Object.keys(user)`에서도 키가 심볼인 프로퍼티는 배제됩니다. '심볼형 프로퍼티 숨기기(hiding symbolic property)'라 불리는 이런 원칙 덕분에 외부 스크립트나 라이브러리는 심볼형 키를 가진 프로퍼티에 접근하지 못합니다.
218
-
=======
219
-
// the direct access by the symbol works
220
-
alert( "Direct: " + user[id] ); // Direct: 123
221
-
```
177
+
[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys)에서도 키가 심볼인 프로퍼티는 무시됩니다. 이는 "심볼형 프로퍼티 숨기기(hiding symbolic properties)" 원칙의 일환입니다. 만약 외부 스크립트나 라이브러리가 우리가 만든 객체를 반복문으로 순회하더라도, 심볼형 프로퍼티에 의도치 않게 접근하는 일은 발생하지 않습니다.
178
+
222
179
223
-
[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) also ignores them. That's a part of the general "hiding symbolic properties" principle. If another script or a library loops over our object, it won't unexpectedly access a symbolic property.
224
-
>>>>>>> upstream/master
225
180
226
181
그런데 [Object.assign](mdn:js/Object/assign)은 키가 심볼인 프로퍼티를 배제하지 않고 객체 내 모든 프로퍼티를 복사합니다.
In JavaScript, as we can see, that's true for global symbols.
273
-
>>>>>>> upstream/master
274
225
```
275
226
276
227
### Symbol.keyFor
277
228
278
-
<<<<<<< HEAD
279
229
전역 심볼을 찾을 때 사용되는 `Symbol.for(key)`에 반대되는 메서드도 있습니다. `Symbol.keyFor(sym)`를 사용하면 이름을 얻을 수 있습니다.
280
-
=======
281
-
We have seen that for global symbols, `Symbol.for(key)` returns a symbol by name. To do the opposite -- return a name by global symbol -- we can use: `Symbol.keyFor(sym)`:
282
-
>>>>>>> upstream/master
283
230
284
231
예시:
285
232
@@ -295,11 +242,7 @@ alert( Symbol.keyFor(sym2) ); // id
295
242
296
243
`Symbol.keyFor`는 전역 심볼 레지스트리를 뒤져서 해당 심볼의 이름을 얻어냅니다. 검색 범위가 전역 심볼 레지스트리이기 때문에 전역 심볼이 아닌 심볼에는 사용할 수 없습니다. 전역 심볼이 아닌 인자가 넘어오면 `Symbol.keyFor`는 `undefined`를 반환합니다.
297
244
298
-
<<<<<<< HEAD
299
245
전역 심볼이 아닌 모든 심볼은 `description` 프로퍼티가 있습니다. 일반 심볼에서 이름을 얻고 싶으면 `description` 프로퍼티를 사용하면 됩니다.
300
-
=======
301
-
That said, all symbols have the `description` property.
302
-
>>>>>>> upstream/master
303
246
304
247
예시:
305
248
@@ -339,21 +282,11 @@ alert( localSymbol.description ); // name
339
282
340
283
심볼의 주요 유스 케이스는 다음과 같습니다.
341
284
342
-
<<<<<<< HEAD
343
285
1. 객체의 '숨김' 프로퍼티 --
344
286
외부 스크립트나 라이브러리에 '속한' 객체에 새로운 프로퍼티를 추가해 주고 싶다면 심볼을 만들고, 이를 프로퍼티 키로 사용하면 됩니다. 키가 심볼인 경우엔 `for..in`의 대상이 되지 않아서 의도치 않게 프로퍼티가 수정되는 것을 예방할 수 있습니다. 외부 스크립트나 라이브러리는 심볼 정보를 갖고 있지 않아서 프로퍼티에 직접 접근하는 것도 불가능합니다. 심볼형 키를 사용하면 프로퍼티가 우연히라도 사용되거나 덮어씌워 지는 걸 예방할 수 있습니다.
345
-
=======
346
-
1. "Hidden" object properties.
347
-
348
-
If we want to add a property into an object that "belongs" to another script or a library, we can create a symbol and use it as a property key. A symbolic property does not appear in `for..in`, so it won't be accidentally processed together with other properties. Also it won't be accessed directly, because another script does not have our symbol. So the property will be protected from accidental use or overwrite.
349
-
>>>>>>> upstream/master
350
287
351
288
이런 특징을 이용하면 원하는 것을 객체 안에 '은밀하게' 숨길 수 있습니다. 외부 스크립트에선 우리가 숨긴 것을 절대 볼 수 없습니다.
352
289
353
290
2. 자바스크립트 내부에서 사용되는 시스템 심볼은 `Symbol.*`로 접근할 수 있습니다. 시스템 심볼을 이용하면 내장 메서드 등의 기본 동작을 입맛대로 변경할 수 있습니다. [iterable 객체](info:iterable)에선 `Symbol.iterator`를, [객체를 원시형으로 변환하기](info:object-toprimitive)에선 `Symbol.toPrimitive`이 어떻게 사용되는지 알아보겠습니다.
354
291
355
-
<<<<<<< HEAD
356
292
사실 심볼을 완전히 숨길 방법은 없습니다. 내장 메서드 [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols)를 사용하면 모든 심볼을 볼 수 있고, 메서드 [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys)는 심볼형 키를 포함한 객체의 *모든* 키를 반환해줍니다. 그런데 대부분의 라이브러리, 내장 함수 등은 이런 메서드를 사용하지 않습니다.
357
-
=======
358
-
Technically, symbols are not 100% hidden. There is a built-in method [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) that allows us to get all symbols. Also there is a method named [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys of an object including symbolic ones. But most libraries, built-in functions and syntax constructs don't use these methods.
0 commit comments