📃 객체끼리 더하고, 빼는 연산을 하면 어떻게 될까 모든 경우에서 객체는 원시값으로 변환되고, 의도한 연산이 수행됨.
- 객체는 예외없이 논리평가시 true를 반환, 따라서 객체는 숫자형이나 문자형으로만 형 변환 됨.
- 숫자형으로 변환된 객체는 수학 연산을 할 떄나 수학 관련 함수를 적용할 때 적용.
- 문자형으로 형 변환은 대개 alert(obj) 같이 객체를 출력하라고 할 때 일어남.
📃 ToPrimitive을 사용하면 숫자형이나 문자형으로의 변환을 원하는 대로 조절 가능함, 객체의 형 변환은 세 종류로 구분되는데 hint라 불리는 값이 구분 기준이 됨, 목표로 하는 자료형 정도로 이해하면 편함.
📃 alert 함수 같이 문자열을 기대하는 연산을 수행할 때는(객체-문자형 변환), hint가 string이 됨.
// 객체를 출력하려고 함
alert(obj);
// 객체를 프로퍼티 키로 사용하고 있음
anotherObj[obj] = 123;
📃 수학 연산을 적용하려 할 때(객체-숫자형 변환), hint가 number이 됨.
// 명시적 형 변환
let num = Number(obj);
// (이항 덧셈 연산을 제외한) 수학 연산
let n = +obj; // 단항 덧셈 연산
let delta = date1 - date2;
// 크고 작음 비교하기
let greater = user1 > user2;
📃 연산자가 기대하는 자료형이 확실하지 않을 때, 아주 드물게 발생함.
// 이항 덧셈 연산은 hint로 `default`를 사용합니다.
let total = obj1 + obj2;
// obj == number 연산은 hint로 `default`를 사용합니다.
if (user == 1) { ... };
📃 이 심볼은 아래와 같이 목표로 하는 자료형(hint)을 명명하는데 사용함.
obj[Symbol.toPrimitive] = function(hint){
// 반드시 원시값을 반환해야 합니다.
// hint는 string, number, default 중 하나가 될 수 있음.
}
ex)
let user = {
name: "John",
money: 1000,
[Symbol.toPrimitive](hint) {
alert(`hint: ${hint}`);
return hint == "string" ? `{name: "${this.name}"}` : this.money;
}
};
// 데모:
alert(user); // hint: string -> {name: "John"}
alert(+user); // hint: number -> 1000
alert(user + 500); // hint: default -> 1500
✏️ user 는 힌트에 따라 문자열로 변환되기도, 숫자로 변환되기도 함.
📃 이런 메서드를 사용하면 형 변환을 직접 구현 할 수 있음.
- 객체는 예외없이 논리평가시 true를 반환, 따라서 객체는 숫자형이나 문자형으로만 형 변환 됨.
- 숫자형으로 변환된 객체는 수학 연산을 할 떄나 수학 관련 함수를 적용할 때 적용.
- 문자형으로 형 변환은 대개 alert(obj) 같이 객체를 출력하라고 할 때 일어남.
ex)
let user = {
name: "John",
money: 1000,
// hint가 "string"인 경우
toString() {
return `{name: "${this.name}"}`;
},
// hint가 "number"나 "default"인 경우
valueOf() {
return this.money;
}
};
alert(user); // toString -> {name: "John"}
alert(+user); // valueOf -> 1000
alert(user + 500); // valueOf -> 1500
✏️ 출력 결과가 Symbol.toPrimitive를 사용한 예제와 완전히 동일하다는 걸 확인할 수 있음.