Skip to content

Commit 229d38b

Browse files
committed
[객체를 원시형으로 변환] 리뷰 반영 — 누락 문장 보강 및 단락 구조 정리
1 parent a38f8ff commit 229d38b

1 file changed

Lines changed: 25 additions & 18 deletions

File tree

  • 1-js/04-object-basics/09-object-toprimitive

1-js/04-object-basics/09-object-toprimitive/article.md

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
`obj1 + obj2` 처럼 객체끼리 더하는 연산을 하거나, `obj1 - obj2` 처럼 객체끼리 빼는 연산을 하면 어떤 일이 일어날까요? `alert(obj)`로 객체를 출력할 때는 무슨 일이 발생할까요?
55

6-
Ruby나 C++ 같은 다른 프로그래밍 언어와 달리, 덧셈(이나 다른 연산)을 처리하기 위한 특별한 객체 메서드를 구현할 수 없죠.
6+
자바스크립트에서는 객체 대상 연산자가 어떻게 동작할지 커스터마이징할 수 없습니다. Ruby나 C++ 같은 다른 프로그래밍 언어와 달리, 덧셈(이나 다른 연산)을 처리하기 위한 특별한 객체 메서드를 구현할 수 없죠.
77

88
객체에 이런 연산을 수행하면 객체는 원시값으로 자동 변환되고, 이후 이 원시값들을 대상으로 연산이 수행되어 최종적으로 원시값이 반환됩니다.
99

@@ -18,20 +18,24 @@ Ruby나 C++ 같은 다른 프로그래밍 언어와 달리, 덧셈(이나 다른
1818
우리가 이를 배우는 목적은 두 가지입니다.
1919

2020
1. 코딩 실수로 인해 의도치 않게 객체 연산이 발생했을 때, 내부적으로 어떤 일이 벌어지는지 이해하기 위해서입니다.
21-
2221
2. 이런 연산이 가능하며 심지어 유용하게 쓰이는 예외적인 상황이 있기 때문입니다. 날짜(`Date` 객체)를 빼거나 비교하는 경우가 대표적인데, 이에 대해서는 나중에 다루겠습니다.
2322

23+
## 형 변환 규칙
2424

2525
<info:type-conversions> 챕터에선 객체의 형 변환은 다루지 않았습니다. 원시형 자료가 어떻게 문자, 숫자, 논리형으로 변환되는지만 알아보았죠. 이젠 메서드와 심볼에 대한 지식을 갖추었으니 본격적으로 이 공백을 메꿔봅시다.
2626

2727
1. 객체는 논리 평가 시 `true`를 반환합니다. 단 하나의 예외도 없죠. 따라서 객체는 숫자형이나 문자형으로만 형 변환이 일어난다고 생각하시면 됩니다.
2828
2. 숫자형으로의 형 변환은 객체끼리 빼는 연산을 할 때나 수학 관련 함수를 적용할 때 일어납니다. 객체 `Date`끼리 차감하면(`date1 - date2`) 두 날짜의 시간 차이가 반환됩니다. `Date`에 대해선 <info:date>에서 다룰 예정입니다.
29-
3. 문자형으로의 형 변환은 대개 `alert(obj)`같이 객체를 출력하려고 할 때 일어납니다.
30-
31-
We can implement string and numeric conversion by ourselves, using special object methods.
29+
3. 문자형으로의 변환은 대개 `alert(obj)`를 사용해 객체를 출력할 때나 이와 유사한 상황에서 발생합니다.
3230

3331
특수 객체 메서드를 사용하면 숫자형이나 문자형으로의 형 변환을 원하는 대로 조절할 수 있습니다.
3432

33+
이제 기술적인 세부 사항들을 살펴봅시다. 이 주제를 깊이 있게 다루려면 이 방법밖에 없으니까요.
34+
35+
## 힌트 (Hint)
36+
37+
자바스크립트는 어떤 변환을 적용할지 어떻게 결정할까요?
38+
3539
객체 형 변환은 세 종류로 구분되는데, 'hint'라 불리는 값이 구분 기준이 됩니다. 'hint'가 무엇인지는 [명세서](https://tc39.github.io/ecma262/#sec-toprimitive)에 자세히 설명되어 있는데, '목표로 하는 자료형' 정도로 이해하시면 될 것 같습니다.
3640

3741
`"string"`
@@ -79,13 +83,11 @@ We can implement string and numeric conversion by ourselves, using special objec
7983

8084
크고 작음을 비교할 때 쓰이는 연산자 `<`, `>` 역시 피연산자에 문자형과 숫자형 둘 다를 허용하는데, 이 연산자들은 hint를 'number'로 고정합니다. hint가 'default'가 되는 일이 없죠. 이는 하위 호환성 때문에 정해진 규칙입니다.
8185

82-
실제 일을 할 때는 이런 사항을 모두 외울 필요는 없습니다. `Date` 객체를 제외한 모든 내장 객체는 hint가 `"default"`인 경우와 `"number"`인 경우를 동일하게 처리하기 때문입니다. 우리도 커스텀 객체를 만들 땐 이런 규칙을 따르면 됩니다.
86+
실제 일을 할 때는 이런 사항을 모두 외울 필요는 없습니다.
87+
88+
`Date` 객체를 제외한 모든 내장 객체는 hint가 `"default"`인 경우와 `"number"`인 경우를 동일하게 처리하기 때문입니다. 우리도 커스텀 객체를 만들 땐 이런 규칙을 따르면 됩니다.
8389

84-
```smart header="`\"boolean\"` hint는 없습니다."
85-
hint는 총 세 가지입니다. 아주 간단하죠.
86-
87-
'boolean' hint는 존재하지 않습니다. 모든 객체는 그냥 `true`로 평가됩니다. 게다가 우리도 내장 객체에 사용되는 규칙처럼 `"default"``"number"`를 동일하게 처리하면, 결국엔 두 종류의 형 변환(객체-문자형, 객체-숫자형)만 남게 됩니다.
88-
```
90+
그럼에도 불구하고 이 3가지 hint에 대해 모두 알고 있는 것은 중요합니다. 그 이유는 곧 알게 될 것입니다.
8991

9092
**자바스크립트는 형 변환이 필요할 때, 아래와 같은 알고리즘에 따라 원하는 메서드를 찾고 호출합니다.**
9193

@@ -105,7 +107,9 @@ obj[Symbol.toPrimitive] = function(hint) {
105107
};
106108
```
107109

108-
실제 돌아가는 예시를 살펴보는 게 좋을 것 같네요. `user` 객체에 객체-원시형 변환 메서드 `obj[Symbol.toPrimitive](hint)`를 구현해보겠습니다.
110+
Symbol.toPrimitive 메서드가 존재하면 모든 hint에 이 메서드가 사용되므로, 다른 메서드는 더 이상 필요 없습니다.
111+
112+
예를 들어, 아래 예시의 user 객체는 이 메서드를 구현하고 있습니다.
109113

110114
```js run
111115
let user = {
@@ -133,8 +137,9 @@ alert(user + 500); // hint: default -> 1500
133137

134138
객체에 `Symbol.toPrimitive`가 없으면 자바스크립트는 아래 규칙에 따라 `toString`이나 `valueOf`를 호출합니다.
135139

136-
- hint가 'string'인 경우: `toString -> valueOf` 순(`toString`이 있다면 `toString`을 호출, `toString`이 없다면 `valueOf`를 호출함)
137-
- 그 외: `valueOf -> toString`
140+
- `"string"` hint인 경우: `toString` 메서드를 호출합니다. 만약 `toString`이 없거나 `toString`이 원시값이 아닌 객체를 반환한다면 `valueOf`를 호출합니다. (따라서 문자형 변환 시에는 `toString`이 우선순위를 가집니다.)
141+
142+
- 그 외의 hint인 경우: `valueOf` 메서드를 호출합니다. 만약 `valueOf`가 없거나 `valueOf`가 원시값이 아닌 객체를 반환한다면 `toString`를 호출합니다. (따라서 수학 연산 시에는 `valueOf`가 우선순위를 가집니다.)
138143

139144
이 메서드들은 반드시 원시값을 반환해야합니다. `toString`이나 `valueOf`가 객체를 반환하면 그 결과는 무시됩니다. 마치 메서드가 처음부터 없었던 것처럼 되어버리죠.
140145

@@ -261,9 +266,9 @@ alert(obj + 2); // 22("2" + 2), 문자열이 반환되기 때문에 문자열끼
261266
원시값을 기대하는 내장 함수나 연산자를 사용할 때 객체-원시형으로의 형 변환이 자동으로 일어납니다.
262267

263268
객체-원시형으로의 형 변환은 hint를 기준으로 세 종류로 구분할 수 있습니다.
264-
- `"string"` (`alert` 같이 문자열을 필요로 하는 연산)
265-
- `"number"` (수학 연산)
266-
- `"default"` (드물게 발생함)
269+
- `"string"` (`alert` 함수나 문자열을 필요로 하는 다른 연산에 사용)
270+
- `"number"` (수학 연산에 사용)
271+
- `"default"` (소수의 연산자에 사용되며, 대부분의 객체는 이를 `"number"`와 동일하게 처리)
267272

268273
연산자별로 어떤 hint가 적용되는지는 명세서에서 찾아볼 수 있습니다. 연산자가 기대하는 피연산자를 '확신할 수 없을 때'에는 hint가 `"default"`가 됩니다. 이런 경우는 아주 드물게 발생합니다. 내장 객체는 대개 hint가 `"default"`일 때와 `"number"`일 때를 동일하게 처리합니다. 따라서 실무에선 hint가 `"default"`인 경우와 `"number"`인 경우를 합쳐서 처리하는 경우가 많습니다.
269274

@@ -275,4 +280,6 @@ alert(obj + 2); // 22("2" + 2), 문자열이 반환되기 때문에 문자열끼
275280
3. 1과 2에 해당하지 않고, hint가 `"number"``"default"`라면
276281
- `obj.valueOf()``obj.toString()`을 호출합니다.
277282

278-
`obj.toString()`만 사용해도 '모든 변환'을 다 다룰 수 있기 때문에, 실무에선 `obj.toString()`만 구현해도 충분한 경우가 많습니다. 반환 값도 '사람이 읽고 이해할 수 있는' 형식이기 때문에 실용성 측면에서 다른 메서드에 뒤처지지 않습니다. `obj.toString()`은 로깅이나 디버깅 목적으로도 자주 사용됩니다.
283+
이 모든 메서드는 (정의되었다면) 정상적으로 동작하기 위해 반드시 원시값을 반환해야 합니다.
284+
285+
실무에서는 로그 출력이나 디버깅 용도로 객체를 사람이 읽기 쉬운 형태로 표현하기 위해, 모든 문자형 변환을 도맡아 처리하는 `obj.toString()` 하나만 구현해 두는 경우가 많습니다

0 commit comments

Comments
 (0)