객체라는 타입은 원시형으로 형변환이 가능하다.
예를들어 객체끼리 더하기 또는 빼기를 한다거나
alert
를 통하여 객체를 매개변수로 넣어준다거나
이럴 경우에는 자동 형 변환이 일어난다.
객체는 원시값으로 변환되고 연산이 수행된다.
alert
의 매개변수로 주는것처럼 객체를 출할때 일어난다.객체 형 변환은 세 종류로 구분하는데 hint
라고 하는 값이 기준이 된다.
hint
란 '목표로 하는 자료형'정도로 이해하면 된다.
문자열을 기대하는 연산을 수행할 때는 hint = string
이 된다.
alert(obj); // 객체를 출력
defObj[obj] = 123; // 객체를 프로퍼티 키로 사용
수학 연산을 적용할 때 hint = number
가 된다.
let num = Number(obj); // 숫자형으로 명시적 형 변환
let n = +obj; // 단항 덧셈 연산으로 자동 형 변환
let difDate = date1 - date2; // 객체의 뺄셈
let samll = user1 < user2; // 비교 연산
자료형이 확실치 않을 때 hint = default
가 된다.
드물게 발생하며, +
연산자를 사용해 이항 덧셈 연산을 한다면,
문자열 더하기가 될 수 있고, 숫자 더하기가 될 수 있다.
따라서 객체끼리 더하기를 할 경우 default
가 된다.
또한 ==
동등 연산자를 사용하게 된다면 객체를 어떤 자료형으로 바꿔야 할지 모르기 때문에 defult
가 된다.
let total = obj1 + obj2; // default
let (user === 1); // default
자바스크립트엔 Symbol.toPrimitive
라는 내장 심볼이 존재
이 심볼은 목표로 하는 자료형(hint)을 명명하는데 사용
obj[Symbol.toPrimitive] = function(hint) { // 원시값을 반환 // hint는 "string", "number", "default"중 하나 };
아래에 객체-원시형 변환 메서드를 구현한 예제
let user = { name: "quakka", money: 1000, [Symbol.toPrimitive](hint) { alert(`hint: ${hint}`); return hint == "string" ? `{name: "${this.name}"}` : this.money; } }; // testCase alert(user); // hint: string -> {name: "jogn"} alert(+user); // hint: number -> 1000 alert(user + 500); // hint: default -> 1500
심볼이 생기기 이전에는 toString
과 valueOf
를 이용하여 형변환을 직접 하였다.
객체에 Symbol.toPrimitive가 없으면 아래 규칙에 따라 호출된다.
이 메서드들은 반드시 원시값을 반환해야 한다. 객체를 반환하면 그 결과는 무시가 된다. 메서드가 작동하지 않았던 것처럼...
일반 객체는 아래와 같은 규칙을 따른다
let user = {
name: 'Quakka'
};
alert(user); // [object Object]
alert(user.valueOf() === user); //true
위의 개념을 사용하여 똑같이 예제를 구현하면
let user = {
name: "Quakka",
money: 50000,
toString() {
return `{name: "${this.name}"}`;
},
valueOf() {
return this.money;
}
};
alert(user); // toString -> {name: "John"}
alert(+user); // valueOf -> 50000
alert(user + 500); // valueOf -> 50500
Symbol.toPrimitive와 valueOf가 없으면, toSring이 모든 형 변환을 처리한다.
연산자가 *
일때는 피연산자를 숫자형
으로 변환된다.
객체가 피연산자 일때 아래와 같은 단계를 거친다.
1. 객체는 원시형으로 변화된다.
2. 변환 후 원시값이 원하는 형태가 아니라면 또다시 현 변환이 된다.
let obj = {
toString() {
return "19";
}
};
console.log(obj * 2); // 4
"2"
가 반환된다.만약 *
가 아닌 +
라면 "22"가 결과값이 되었을 것이다.