본문 바로가기
JavaScript

JavaScript 객체의 형변환

by 하이방가루 2022. 2. 25.
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 ) { ... }

자바스크립트의 형 변환 알고리즘

  1. 객체에 obj[Symbol.toPrimitive](hint)메서드가 있는지 찾고, 있다면 메서드를 호출한다. (Symbol.toPrimitive는 시스템 심볼로, 심볼형 키로 사용된다.)
  2. 1에 해당하지 않고, hint가 "string"이라면 obj.toString()이나 obj.valueOf()를 호출한다. (존재하는 메서드만 실행)
  3. 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

댓글