25. 객체의 원시형

Chipmunk_jeong·2021년 3월 2일
0

TIL

목록 보기
25/62
post-thumbnail

객체라는 타입은 원시형으로 형변환이 가능하다.
예를들어 객체끼리 더하기 또는 빼기를 한다거나
alert를 통하여 객체를 매개변수로 넣어준다거나
이럴 경우에는 자동 형 변환이 일어난다.
객체는 원시값으로 변환되고 연산이 수행된다.

  • 객체의 boolean타입은 무조건 true가 나온다.
  • 따라서 객체는 문자와 숫자로 형변환이 일어난다고 생각하면 된다.
  • 숫자형으로 형 변환은 객체끼리 수학관련 연산 또는 함수를 적요할 때 발생한다.
  • 문자형으로 형 변환은 alert의 매개변수로 주는것처럼 객체를 출할때 일어난다.

원시형으로

객체 형 변환은 세 종류로 구분하는데 hint라고 하는 값이 기준이 된다.
hint란 '목표로 하는 자료형'정도로 이해하면 된다.

"string"

문자열을 기대하는 연산을 수행할 때는 hint = string이 된다.

alert(obj); // 객체를 출력

defObj[obj] = 123; // 객체를 프로퍼티 키로 사용

"number"

수학 연산을 적용할 때 hint = number가 된다.

let num = Number(obj); // 숫자형으로 명시적 형 변환

let n = +obj; // 단항 덧셈 연산으로 자동 형 변환
let difDate = date1 - date2; // 객체의 뺄셈

let samll = user1 < user2; // 비교 연산

"default"

자료형이 확실치 않을 때 hint = default가 된다.
드물게 발생하며, +연산자를 사용해 이항 덧셈 연산을 한다면,
문자열 더하기가 될 수 있고, 숫자 더하기가 될 수 있다.
따라서 객체끼리 더하기를 할 경우 default가 된다.
또한 ==동등 연산자를 사용하게 된다면 객체를 어떤 자료형으로 바꿔야 할지 모르기 때문에 defult가 된다.

let total = obj1 + obj2; // default
let (user === 1); // default

Symbol.toPrimitive

자바스크립트엔 Symbol.toPrimitive라는 내장 심볼이 존재
이 심볼은 목표로 하는 자료형(hint)을 명명하는데 사용

obj[Symbol.toPrimitive] = function(hint) {
  // 원시값을 반환
  // hint는 "string", "number", "default"중 하나
};

아래에 객체-원시형 변환 메서드를 구현한 예제

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

// testCase
alert(user); // hint: string -> {name: "jogn"}
alert(+user); // hint: number -> 1000
alert(user + 500); // hint: default -> 1500

toString과 valueOf

심볼이 생기기 이전에는 toStringvalueOf를 이용하여 형변환을 직접 하였다.

객체에 Symbol.toPrimitive가 없으면 아래 규칙에 따라 호출된다.

  • hint 'string' : toString -> valueOf 순
  • 그 외 : valueOf -> toString 순

이 메서드들은 반드시 원시값을 반환해야 한다. 객체를 반환하면 그 결과는 무시가 된다. 메서드가 작동하지 않았던 것처럼...

일반 객체는 아래와 같은 규칙을 따른다

  • toString은 "[object Objed]"를 반환
  • valueOf는 객체 자신을 반환
let user = {
  name: 'Quakka'
};
alert(user); // [object Object]
alert(user.valueOf() === user); //true

위의 개념을 사용하여 똑같이 예제를 구현하면

let user = {
  name: "Quakka",
  money: 50000,

  toString() {
    return `{name: "${this.name}"}`;
  },

  valueOf() {
    return this.money;
  }

};

alert(user); // toString -> {name: "John"}
alert(+user); // valueOf -> 50000
alert(user + 500); // valueOf -> 50500

Symbol.toPrimitive와 valueOf가 없으면, toSring이 모든 형 변환을 처리한다.


추가 형 변환

연산자가 *일때는 피연산자를 숫자형으로 변환된다.
객체가 피연산자 일때 아래와 같은 단계를 거친다.
1. 객체는 원시형으로 변화된다.
2. 변환 후 원시값이 원하는 형태가 아니라면 또다시 현 변환이 된다.

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

console.log(obj * 2); // 4
  1. obj * 2에서 obj가 원시형으로 변환되어 toString을 통해 "2"가 반환된다.
  2. "2" * 2는 문자에 숫자를 곱하는것이라 원치않은 형태이다.
    그래서 "2"를 한번더 숫자형으로 형변황이 되어 2 * 2가 된다.

만약 *가 아닌 +라면 "22"가 결과값이 되었을 것이다.

profile
Web Developer

0개의 댓글