객체의 자동 형 변환
객체끼리 서로 더하거나, 빼거나 , alert으로 객체를 출력하거나 할 때 객체는 자동 형 변환을 합니다.
예는 다음과 같습니다!
1. 객체는 논리 평가 시 true를 반환합니다. 고로 객체는 숫자형, 문자형 2개로만 변환이 일어납니다!
2. 객체끼리 빼는 연산을 하거나, 수학 관련 함수를 적용할 때 객체는 숫자형으로 형 변환 합니다.
ex) Date객체끼리 빼는 연산을 하면 두 날짜의 시간차이가 반환 됩니다. ( 숫자형 형 변환 )
3. 객체를 출력하려고 할 때 문자형으로 형 변환 합니다.
객체 자동 형 변환의 기준 hint
객체 형 변환은 세 종류로 구분되고 hint라 불리는 값이 구분 기준입니다.
hint == 목표로 하는 자료형 정도로 이해하고 넘어갑니다.
1. alert 함수와 같이 문자열을 기대하는 연산을 수행할 때 hint는 'string' 입니다.
2. 이항 덧셈 연상을 제외한 수학 연산을 수행할 때 hint는 'number' 입니다.
3. 연산자가 기대하는 자료형이 확실하지 않을 때 hint는 'default' 입니다.
ex) 이항 덧셈 연산자 + 의 경우 자료형에 따라 문자열을 합치는 연산을 할 수도 있고,
숫자를 더해주는 연산을 할 수도 있습니다. 따라서 + 의 인수가 객체이면 hint는 'defalut' 입니다.
ex) 동등 연산자 == 를 사용해 객체-문자형, 객체-숫자형, 객체-심볼형 끼리 비교할 때도 hint는 'defalut' 입니다.
ex) >, < 연산자는 피연산자로 문자형과 숫자형 둘 다 허용 하는데 hint는 number 고정입니다.
위와 같은 규칙들을 외울 필요는 없습니다!
Date 객체를 제외한 모든 내장 객체는 hint가 defalut 인 경우와 number 인 경우를 동일하게 처리합니다.
객체 형 변환 알고리즘
자바스크립트는 객체의 형 변환이 필요할 때, 아래 순서의 알고리즘에 따라 매서드를 찾고 호출합니다.
1. 객체에 obj [Symbol.toPrimitive](hint) 메서드가 있는지 찾고 호출합니다.
Symbol.toPrimitive는 시스템 심볼로, 심볼형 키로 사용됩니다.
2. 1에 해당하지 않고 hint가 'string'이라면 obj.toString() 이나 obj.valueOf() 를 호출합니다.
3. 1,2에 해당하지 않고 hint가 'number' or 'defalut'이면 obj.valueOf() 나 obj.toString()을 호출합니다
obj [Symbol.toPrimitive](hint) 메서드 구현 및 이해
let user = {
name: 'John',
grade : 100,
[Symbol.toPrimitive](hint){
console.log(hint)
console.log(hint == 'string' ? this.name : this.grade)
return hint == 'string' ? this.name : this.grade
}
}
alert(user) // alert john 출력
alert(+user) // alert 100 출력
alert(user - 50) // alert 50 출력
[Symbol.toPrimitive](hint) 매서드를 구현했습니다.
user의 형을 바꾸려고 하면 자바스크립트는 [Symbol.toPrimitive](hint) 매서드를 호출합니다.
문자형
1. alert(user)로 출력하려 하면 객체는 문자형으로 형 변환 합니다.
2. 이때 hint는 string이 되고 메소드의 실행으로 this.name이 return 됩니다.
3. alert(user)의 결과는 john이 됩니다.
숫자형
1. alert(+user)로 수학연산을 하려하면 객체는 숫자형으로 형 변환 합니다.
2. 이때 hint는 number가 되고 메소드의 실행으로 this.grade가 return 됩니다.
3. alert(+user)의 결과는 100이 됩니다.
위와 같은 메소드를 구현해 놓으면 객체의 형 변환 시 원하는 결과값을 리턴하도록 할 수 있습니다!
2. toString() , valueOf() 메소드의 구현 및 이해
객체에 [Symbol.toPrimitive](hint) 메소드가 없고
hint가 string이면 toString() --> 없다면 --> valueOf() 순으로 호출하고
그외의 경우엔 ( number. default ) valueOf() --> 없다면 --> toString() 순으로 호출합니다.
위 2개의 메소드는 반드시 원시값을 리턴해야합니다.
객체를 리턴하면 결과가 무시됩니다. ( 메소드가 없었던 것 처럼 됩니다. )
일반적인 객체에서
toString()은 문자열 "[object Object]" 를 리턴합니다.
valueOf()는 객체 자신을 리턴합니다. ( 무시됩니다. )
let user1 = {
name: 'John',
grade : 100,
}
alert(user1) // [object Object]
위 2개의 메소드를 직접 구현해 보겠습니다.
let user1 = {
name: 'John',
grade : 100,
toString(){
return this.name
},
valueOf(){
return this.grade
}
}
alert(user1) // john
alert(+user1) // 100
문자형
1. alert(user1) 처럼 객체를 출력하려 할 때 hint는 string 입니다.
2. toString() 매소드를 호출합니다.
3. this.name이 리턴됩니다.
숫자형
1. alert(+user1) 처럼 객체로 수학연산을 하려 할 때 hint는 number 입니다.
2. valueOf() 매소드를 호출합니다.
3. this.grade가 리턴됩니다.
위 [Symbol.toPrimitive](hint) 메소드를 사용한 예제와 완벽하게 일치합니다!
간혹 모든 형 변환을 한 곳에서 처리해야 하는 경우도 생깁니다!
let user = {
name: "John",
toString() {
return this.name;
}
};
alert(user); // John
alert(user+10); // John10
이럴 땐 toString() 메소드만 구현해 주면 됩니다.객체에 [Symbol.toPrimitive](hint) 메소드와 valueOf() 메소드가 없다면, hint와 상관없이 toString이 모든 형 변환을 처리합니다.
'Frontend > JS.info 정리' 카테고리의 다른 글
자료구조와 자료형 - 숫자형 (0) | 2022.01.18 |
---|---|
자료구조와 자료형 - 원시값의 메소드 (0) | 2022.01.16 |
객체: 기본 - 심볼 ( Symbol ) (0) | 2021.12.27 |
객체: 기본 - optional chaining ( ?. ) (0) | 2021.12.22 |
객체: 기본 - new , constructor (0) | 2021.12.21 |