ABOUT ME

-

Total
-
  • JS: valueOf, toString, toPrimitive
    컴퓨터/HTML & JS & TS 2022. 10. 14. 17:26
    728x90
    반응형

    Javascript 기능 중 valueOf, toString, toPrimitive를 이용하면 말이 안 되는 것을 할 수 있다.

    // 기본적으로 toString은 아래처럼 쓰일 수 있다.
    let a = {
      id: '123oij21312838',
      toString() {
        return '한글';
      },
    };
    
    if (a == '한글') {
      console.log('a는 한글');
    }
    
    // 결과: a는 한글 출력됨

     

    자바스크립트 타입 전환 룰 @itnext.io Terry Su

    위에 따르면 아래처럼 진행된다.

    // a가 string
    'a' == a is True
    
    // a가 boolean
    True == 1 is True
    
    // a가 object => conversion

     

    toPrimitive

    @객체를 원시형으로 변환하기

    object가 숫자형이나 문자형으로 형 변환시 toPrimitive를 이용할 수 있다.

    let user = {
      name: "John",
      money: 1000,
    
      [Symbol.toPrimitive](hint) {
        alert(`hint: ${hint}`);
        return hint == "string" ? `{name: "${this.name}"}` : this.money;
      }
    };
    
    // 데모:
    alert(user); // hint: string -> {name: "John"}
    alert(+user); // hint: number -> 1000
    alert(user + 500); // hint: default -> 1500

     

    하지만 object에 toPrimitive 함수가 없다면 기본적으로 valueOftoString을 먼저 lookup 한다.

    let user = {
      name: "John",
      money: 1000,
    
      // hint가 "string"인 경우
      toString() {
        return `{name: "${this.name}"}`;
      },
    
      // hint가 "number"나 "default"인 경우
      valueOf() {
        return this.money;
      }
    
    };
    
    alert(user); // toString -> {name: "John"}
    alert(+user); // valueOf -> 1000
    alert(user + 500); // valueOf -> 1500

     

    그럼 여기서 생기는 궁금증은 valueOf, toString, toPrimitive가 전부 다 있다면? (물론 === 로는 안 통한다)

    1. Symbol.toPrimitive 메소드를 찾아 부른다.

    2. valueOf 메소드를 찾아 부른다.

    3. toString 메소드를 찾아 부른다. 여기까지 없다면 변환은 에러가 발생함

    let a = {
      name: '가',
    
      valueOf() {
        return 2;
      },
      toString() {
        return '3';
      },
      [Symbol.toPrimitive]() {
        return 4;
      },
    };
    
    console.log(a == '3');  // false
    console.log(a == 4);  // true

     

    a == "가" && a == "나" && a == "다"

    이걸 이용하면 아래와 같이 말이 안 되게 생긴 구문이 가능하다.

    let a = {
      i: 1,
      [Symbol.toPrimitive]() {
        return this.i++;
      },
    };
    
    if (a == 1 && a == 2 && a == 3) {
      console.log('True');
    }
    
    // 결과: True
    728x90

    댓글