[JavaScript] 객체의 원시 값 변환

객체에서 원시 값 변환이란

객체는 원시 값과 다르게 연산에 직접 참여할 수 없습니다. 따라서 객체가 연산에 사용될 때는 자동으로 원시 값으로 변환되는 과정입니다.

객체에서 원시 값 변환되는 상황

  • number hint : 단항 덧셈 연산자(+obj), 이항 뺄셈 연산(obj - obj2), Number(obj), 비교 연산(>,<)
  • string hint : alert(obj), console.log(`${obj}`), String(obj)
  • defulat hint : 이항 덧셈 연산자(obj + obj2), 동등 연산자(==, !=)

객체에서 원시형 변환의 알고리즘

자바스크립트 엔진은 객체가 원시형이 필요할 때 내부적으로  다음 과정을 따릅니다.

  • 객체에 obj[Symbol.toPrimitive](hint) 메서드가 있는지 확인하고 호출합니다.
    • hint 값은 string, number 또는 default입니다.
    • 이 메서드는 반드시 원시값을 반환해야 하며, 반환값이 객체이면 에러가 발생합니다.
  • Symbol.toPrimitive가 없거나 반환값이 적절하지 않다면
    • hint가 string인 경우: 먼저 toString()을 없으면 valueOf()를 호출합니다.
    • hint가 number나 default인 경우 : 먼저 valueOf()를 없으면 toString()을 호출합니다.

Symbol.toPrimitive를 활용한 변환

const currency = {
  amount: 1000,
  unit: "USD",

  // Symbol.toPrimitive 메서드 구현
  [Symbol.toPrimitive](hint) {
    console.log(`Hint: ${hint}`);
    if (hint === "string") {
      // 문자열 컨텍스트: 통화를 읽기 쉬운 형태로 반환
      return `${this.amount} ${this.unit}`;
    } else if (hint === "number") {
      // 숫자 컨텍스트: 원화(KRW)로 변환한 값 반환 (환율: 1 USD = 1300 KRW)
      return this.amount * 1300;
    } else {
      // 기본 컨텍스트: 기본적으로 통화 값 반환
      return this.amount;
    }
  },
};

// 문자열 컨텍스트
console.log(String(currency)); // "1000 USD"

// 숫자 컨텍스트
console.log(+currency); // 1300000 (원화로 변환된 값)

// 기본 컨텍스트 (산술 연산)
console.log(currency + 500); // 1500 (USD 값에 500을 더함)
  • Symbol.toPrimitive는 객체가 원시 값으로 변환될 때의 동작을 커스터마이징할 수 있습니다.
  • hint 매개변수를 통해 컨텍스트를 구분하여 다른 값을 반환할 수 있습니다.

toString()과 valueOf()로 형 변환

Symbol.toPrimitive를 구현하지 않더라도, 객체는 기본적으로 toString()과 valueOf() 메서드를 사용하여 변환됩니다.

const book = {
  title: "JavaScript: The Good Parts",
  author: "Douglas Crockford",
  price: 29.99,

  // 문자열 컨텍스트를 위한 toString() 재정의
  toString() {
    return `${this.title} by ${this.author}`;
  },

  // 숫자,Default 컨텍스트를 위한 valueOf() 재정의
  valueOf() {
    return this.price;
  },
};

// alert()는 문자열 형 변환을 유도하므로 toString()이 호출됩니다.
alert(book);  
// 출력: "JavaScript: The Good Parts by Douglas Crockford"

// 산술 연산 시에는 valueOf()가 호출됩니다.
console.log(book + 10);   
// 출력: 39.99 (29.99 + 10)

// 이항 덧셈 연산자는 피연산자 중 하나가 문자열이면 문자열 연결을 시도합니다.
console.log(book + " is a must-read!");  
// 출력: "JavaScript: The Good Parts by Douglas Crockford is a must-read!"
  • toString()은 객체가 문자열로 변환될 때 호출됩니다.
  • valueOf()는 객체가 숫자로 변환될 때 호출됩니다.

 

'JavaScript' 카테고리의 다른 글

[JavaScript] 숫자 자료형  (0) 2025.02.12
[JavaScript] 원시 값과 메서드  (0) 2025.02.12
[JavaScript] 심볼(Symbol)  (0) 2025.02.12
[JavaScript] 옵셔널 체이닝(?.)  (0) 2025.02.12
[JavaScript] new 연산자와 생성자 함수  (0) 2025.02.11