type coercion
- 타입을 암시적으로 변환
- 엔진이 필요에 따라 자동으로 변환
- 개발자가 예상치 못한 경우 버그 초래
to string
let num = 1;
let str = "one :" + num;
let str_nan = NaN + ''
let str_true = true + ''
let str_obj = ({}) + ''
let str_func = (function(){}) + ''
to number
let str = "1999";
let num = +str;
console.log(num == str)
let str2 = "Hi";
let num2 = +str2;
let num = +{}
let num = +[]
let num = +[10, 20]
let num = +(function(){})
boolean
let truthyValue = "Hello";
let falsyValue = "";
explicit type conversion
to string
let value = String(NaN);
let value = ((Infinity).toString());
to number
let num = Number(" 1000 ");
let num = Number(null);
let num = Number(undefined);
let num = parseInt('-1');
to boolean
let truthyValue = Boolean("Hello");
let falsyValue = Boolean("");
object
- 세 가지 hint
- string
- number
- default
- 반환 타입은 원시 타입
- 단 hint가 string 이어도 number를 반환할 수 있음
조건 | 동작 |
---|
1. obj[Symbol.toPrimitive](hint) 메서드가 있는지 확인 | - 있다면 메서드 호출 |
2. hint 가 "string" | - obj.toString() 호출 (존재하지 않으면 obj.valueOf() 호출) |
3. hint 가 "number" 또는 "default"이면 | - obj.valueOf() 호출 (존재하지 않으면 obj.toString() 호출) |
obj[Symbol.toPrimitive](hint)
메서드가 있는지 확인, 있다면 메서드 호출
let obj = {
[Symbol.toPrimitive](hint) {
if (hint === 'string') {
return "Hello";
} else if (hint === 'number') {
return 99;
} else {
return "Default";
}
}
};
console.log(String(obj));
console.log(Number(obj));
console.log(obj + 2);
obj[Symbol.toPrimitive](hint)
가 없고
hint
가 "string" 이면 obj.toString()
호출
- 존재하지 않으면
obj.valueOf()
호출
let obj = {
toString() {
return "Hello, World!";
}
};
console.log(String(obj));
console.log(Number(obj));
console.log(obj + 2);
obj[Symbol.toPrimitive](hint)
가 없고
hint
가 "number" 또는 "default" obj.valueOf()
호출
- 존재하지 않으면
obj.toString()
호출
let obj = {
valueOf() {
return 42;
}
};
console.log(String(obj));
console.log(Number(obj));
console.log(obj + 2);
let obj = {};
console.log(String(obj));
console.log(Number(obj));
console.log(obj + 2);
- 원시 타입 반환은 보장
- 원하는 hint 타입이 반환되지는 않음
let obj = {
[Symbol.toPrimitive](hint) {
if (hint === 'string') {
return 42;
} else if (hint === 'number') {
return 100;
} else {
return "Default Value";
}
}
};
let obj = {
toString() {
return "99";
}
};
console.log(obj * 10);