728x90
반응형
- 객체는 논리 평가시 단 하나의 예외도 없이 true를 반환한다. (null은 type 검사시 객체로 뜨지만 null객체는 모든 경우에서 따로 평가된다)
ToPrimitive
객체 형 변환은 세 종류로 구분되는데, 'hint'라 불리는 값이 구분 기준이 된다.
hint 가 string이 될 때
- 객체를 출력하려고 할 때
- alert(obj);
- 객체를 프로퍼티 키로 사용할 때
- outerobj[innerobj] = 123;
hint 가 number가 될 때
- 명시적 형 변환
- let num = Number(obj);
- 이항 덕셈 연산을 제외한 수학 연산
- let n = +obj; // 단항 덧셈 연산
- let delta = date1 - date2;
- 크고 작음 비교
- let greater = user1 > user2;
hint 가 default가 될 때
- 아주 드믄 경우로 연산자가 기대하는 자료형이 확실치 않을 때 발생한다.
- 이항 덧셈 연산 : 경우에 따라 문자열 병합일 수 있고, 숫자를 더하는 연산을 할 수도 있다.
- let total = obj1 + obj2;
- 동등 연산자 ==를 사용해 객체 - 문자형, 객체 - 숫자형, 객체 - 심볼형끼리 비교할 때
- if ( user == 1 ) { ... }
자바스크립트의 형 변환 알고리즘
- 객체에 obj[Symbol.toPrimitive](hint)메서드가 있는지 찾고, 있다면 메서드를 호출한다. (Symbol.toPrimitive는 시스템 심볼로, 심볼형 키로 사용된다.)
- 1에 해당하지 않고, hint가 "string"이라면 obj.toString()이나 obj.valueOf()를 호출한다. (존재하는 메서드만 실행)
- 1과 2에 해당하지 않고, hint가 "number"나 "default"라면 obj.valueOf()나 obj.toString()을 호출한다. (존재하는 메서드만 실행)
Symbol.toPrimitive 정의하기
obj[Symbol.toPrimitive] = function(hint) {
// 반드시 원시값을 반환해야 한다.
// hint는 "string", "number", "default" 중 하나가 되야 한다.
}
예시
let wallet = {
name: "Jack",
money: 10000,
[Symbol.toPrimitive](hint) {
alert(`hint: ${hint}`);
return hint == "string" ? `{name: "${this.name}"}` : this.money;
}
};
alert(wallet); // hint: string -> {name: "Jack"}
alert(+wallet); // hint: number -> 1000
alert(wallet + 500); // hint: default -> 1500
toString과 valueOf 호출
Symbol.toPrimitive가 없으면 자바스크립트는 아래 규칙에 따라 toString이나 valueOf를 호출한다.
- hint가 'string'인 경우: toString -> valueOf 순으로 호출(toString이 없을 때 valueOf를 호출)
- 그 외: valueOf -> toString 순
만약 toSring이나 valueOf가 객체를 반환하면 그 결과는 무시된다.
일반 객체는 기본적으로 toString은 문자열 "[object object]"을 반환하고, valueOf는 개체 자신을 반환한다.
예시
let wallet = {name: "John"};
alert(wallet); // [object object]
alert(wallet.valueOf() === wallet); // true
toSring과 valueOf를 조합해 Symbol.toPrimitive를 사용한 예제와 동일하려면
let wallet = {
name: "Jack",
money: 10000,
// hint가 "string"인 경우
toString() {
return `{name: "${this.name}"}`;
},
// hint가 "number"나 "default"인 경우
valueOf() {
return this.money;
}
};
alert(wallet); // hint: string -> {name: "Jack"}
alert(+wallet); // hint: number -> 1000
alert(wallet + 500); // hint: default -> 1500
간혹 모든 형 변환을 한 곳에서 처리해야 하는 경우 한 가지 함수만 구현해 주면 된다.
let user = {
name: "John",
toString() {
return this.name;
}
};
alert(user); // John
alert(user + 500); // John500
728x90
반응형
'JavaScript' 카테고리의 다른 글
JavaScript ) 숫자형 다루기 (0) | 2022.03.01 |
---|---|
JavaScript ) 래퍼 객체 (0) | 2022.03.01 |
JavaScript 심볼형 (0) | 2022.02.14 |
JavaScript this와 체이닝 (0) | 2022.02.10 |
JavaScript 가비지 컬렉션 (0) | 2022.02.10 |
댓글