dolog
객체를 원시형으로 변환하기 본문
객체끼리의 연산과 출력?
- 객체는 원시값으로 변환되고, 그 후 의도한 연산이 진행된다
- 객체는 논리 평가 시 true 반환 ➡️ 숫자형 또는 문자형
- 숫자형으로의 변환 : 빼는 연산, 수학 관련 함수를 적용할 때
ex) date1 - date2 = 두 날짜의 시간 차이가 반환
- 문자형으로의 변환 : console.log(obj), alert(obj) 같이 출력할 때 변환
ToPrimitive
- 특수 객체 매서드를 사용해 숫자형 또는 문자형으로 형 변환을 자유롭게 조절할 수 있다
- ‘hint’(구분 기준) : 목표로 하는 자료형(명세서에 자세한 설명 참고하기)
ㄴ “string” : alert 함수같이 문자열을 기대하는 연산 수행 시
hint ➡️ string (object ➡️ string)
ㄴ “number” : 수학 연산을 적용할 때
hint ➡️ number (object ➡️ number)
ㄴ “default” : 연산자가 기대하는 자료형이 확실하지 않을 때
hint ➡️ default
string
// 객체 출력
alert(obj);
// 객체를 프로퍼티 키로 사용하고 있음
anotherObj[obj] = 123;
number
// 명시적 형 변환
let num = Number(obj);
// (이항 덧셈 연산을 제외한) 수학 연산
let n = +obj; // 단항 덧셈 연산
let delta = date1 - date2;
// 크고 작음 비교하기
let greater = user1 > user2;
default
// 이항 덧셈 연산은 hint로 dafault 를 사용한다
let total = obj1 + obj2; // 문자열을 합쳐주는 건지, 숫자를 더해주는 건지 모르기 때문
// obj == number 연산은 hint로 dafault 를 사용한다
if (user == 1) { … }; // 객체가 다른 형들과 비교할 때 마지막 출력을 무엇으로 할지 모르기 때문
왜 Boolean hint 는 없는가?
- 모든 객체는 true로 평가되기 때문이다
- 또한 결국 내장 객체에 사용되는 규칙처럼 default와 number를 동일하게 처리하면 두 종류의 형 변환만 남게 된다(객체-문자형, 객체-숫자형)
Symbol.toPrimitive
- JS의 내장 심볼로 hint(목표로 하는 자료형)를 명명하는데 사용
- 시스템 심볼로 심볼형 키로 사용된다
- 이 매서드 하나로 모든 종류의 형 변환을 다룰 수 있다(str, num, def)
obj[Symbol.toPrimitive] = function(hint) {
// 반드시 원시값을 반환
// hint는 string, number, default 중 하나가 될 수 있다
};
실제 예시
let user = {
name: “shim”,
money: 1000,
[Symbol.toPrimitive] (hint) {
console.log(`hint ${hint}`);
return hint == “string ? `{name: “${this.name}”}` : this.money;
};
}
console.log(user); // hint : string ➡️ {name: “shim”}
console.log(+user); // hint : number ➡️ 1000
console.log(user + 500); // hint : default ➡️ 1500
JS의 알고리즘 1)
obj[Symbol.toPrimitive]가 객체 안에 있는지 찾고 있다면 예시처럼 매서드 호출
toString과 valueOf
- 심볼이 생기기전 부터 있던 구식 매서드지만, 형 변환을 직접 구현할 수 있다
- Symbol.toPrimitive이 없다면 toString 또는 valueOf 호출
- 반드시 원시값을 반환(만약 객체가 반환되면 무시된다)
hint가 string 인 경우)
toString ➡️ valueOf 순 (toString이 있다면 toString, 없다면 valueOf 호출)
그 외)
valueOf ➡️ toString 순
- toString은 문자열 “[object Object]” 반환
- valueOf은 객체 자신을 반환
let user = { name: “kim” };
console.log(user); // [object Object]
console.log(user.valueOf() === user); // true
실제 예시
let user = {
name: “shim”,
money: 1000,
// hint가 string 인 경우
toString() {
return `{name: “${this.name}”}`;
},
// hint가 number나 default 인 경우
valueOf() {
return this.money;
}
};
// Symbol.toPrimitive 매서드 사용 결과와 동일한 결과
console.log(user); // toString ➡️ {name: “shim”}
console.log(+user); // valueOf ➡️ 1000, 단순히 객체만 반환하기 때문에
console.log(user + 500); // valueOf ➡️ 1500
하지만 모든 형 변환을 한 곳에서 처리해야 한다면 toString 만 사용하면 된다
또한 Symbol.toPrimitive나 valueOf가 없다면 toString이 모든 형 변환 처리한다
반환 타입
- 위 세가지 매서드는 hint에 명시된 자료형으로 형 변환을 보장할 수 없다
- 다만 확신할 수 있는 한가지는 객체가 아닌 원시값을 반환해준다는 것
추가 형 변환 - * 연산자 : 피연산자를 숫자형으로 변환
- 객체가 피연산자일 때 다음 단계를 거쳐 형 변환이 일어난다
- 객체 ➡️ 원시형
- 변환 후 원하는 원시값이 아닌 경우 다시한번 형 변환
let obj = {
// 다른 매서드가 없다면 toString에서 모든 형 변환 처리
toString() {
return “2”;
}
};
console.log(obj * 2); // 4 객체 ➡️ 문자열 ➡️ 숫자형
이항 덧셈 연산의 경우
let obj = {
toString() {
return “2”;
}
};
console.log(obj * 2); // (“2” + 2) ➡️ 22, 문자열 + 문자열
원시값을 기대하는 매서드 또는 연산자 사용시, 객체-원시형으로 자동 형 변환
hint(목표로 하는 자료형)를 기준으로 세가지 : string, number, default
내장 객체는 대게 hint가 default 일때와 number 일때를 동일하게 처리
즉, 실무에서도 합쳐서 처리할 때가 많다
제일 많이 사용하는 것은 toString()으로 모든 형 변환이 가능하기 때문이다
로깅 또는 디버깅 목적으로도 자주 사용된다
• 로깅 ?