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

라용·2022년 11월 17일
0

모던 JavaScript 튜토리얼 내용 일부를 정리 요약한 내용입니다. 더 자세한 설명은 원문 링크를 참고하세요

객체 끼리 더하거나 빼는 연산을 한다면, 객체에서는 자동 형 변환이 일어납니다. 객체는 원시값으로 변환되고 의도한 연산이 수행됩니다. 특수 객체 메서드를 사용하면 숫자형이나 문자형 등 원하는 대로 형변환을 조절할 수 있습니다. 이때 hint 라고 불리는 값이 구분 기준이 됩니다.

alert 함수는 문자열을 기대하는 연산이므로 hint 가 string 이 됩니다.

alert(obj);

anotherObj[obj] = 123;

수학 연산을 적용하면 hint 는 number 가 됩니다.

let num = Number(obj); 
// 명시적 형변환

let n = +obj;
let data = data1 - data2;

let greater = user1 > user2;

연산자가 기대하는 자료형이 확실하지 않다면 hint 는 default 가 됩니다.

let total = obj1 + obj2;

if (user == 1) {...};

모든 객체는 true 이므로 boolean 힌트는 존재하지 않고, 내장 객체에 사용되는 규칙처럼 default 와 number 를 동일하게 처리하면 문자형, 숫자형 형변환 두가지만 남습니다.

자바스크립트는 형 변환이 필요할 때 객체에 objSymbol.toPrimitive 메서드가 있는지 찾고 메서드를 호출합니다. (Symbol.toPrimitive 는 시스템 심볼로 심볼형 키로 사용) hint가 string이라면 obj.toString() 이나 obj.valueOf() 를 호출합니다. number 나 default 라면 obj.valueOf() 나 obj.toString() 을 호출합니다.

user[Symbol.toPrimitive]를 사용하면 메서드 하나로 모든 종류의 형 변환을 다룰 수 있습니다. user 는 hint 에 따라 문자열이나 숫자로 변환됩니다.

let user = {
    name : "mike",
    money : 1000,
    [Symbol.toPrimitive](hint) {
        alert(`hint: ${hint}`);
        return hint == "string" ? `{name: "${this.name}"}` : this.money;
    }
}

alert(user); // hint: string - {name: 'mike'}
alert(+user); // hint: number - 1000
alert(user + 500); // hint: default - 1500

toString() 과 valueOf() 를 사용하면 형변환을 직접 구현할 수 있습니다.

let user = {
    name : "mike",
    money : 1000,

    // hint 가 string
    toString() {
        return `{name: "${this.name}"}`;
    },

    // hint 가 number 나 default
    valueOf() {
        return this.money;
    }
}

alert(user); // hint: string - {name: 'mike'}
alert(+user); // hint: number - 1000
alert(user + 500); // hint: default - 1500

대부분의 연산자와 함수가 피연산자의 형을 변환시킵니다. 곱셈을 해주는 연산자 * 는 피연산자를 숫자형으로 변환시킵니다. 하지만 이항 덧셈 연산은 같은 상황에서 문자열을 연결합니다.

let obj = {
    toString() {
        return "2";
    }
}

alert(obj * 2); // 4
alert(obj + 2); // 22 ("2" + 2)

obj.toString() 만 사용해도 모든 변환을 다룰 수 있으므로 실무에서는 obj.toString() 만 구현해도 충분한 경우가 많습니다. 로깅이나 디버깅 목적으로 자주 사용됩니다.

profile
Today I Learned

0개의 댓글