Frontend/JS.info 정리

객체: 기본 - 객체를 원시형으로 변환하기

Creative_Lee 2022. 1. 11. 12:33

객체의 자동 형 변환

객체끼리 서로 더하거나, 빼거나 , 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이 모든 형 변환을 처리합니다.

 

 

 

 

기본이 중요하다.