본문 바로가기
JAVASCRIPT

[JS][강제변환] 추상연산 ToNumber

by KBS 2022. 2. 9.
728x90

추상연산

ToNumber

'숫자 아닌 값 -> 수식 연산이 가능한 숫자' 변환 로직은 ES5 9.3 ToNumber 추상 연산에 잘 정의되어있다.

 

예를 들어 true는 1, false는 0이 된다. undefinedNaN으로, null은 0으로 바뀐다.

 

문자열 값에 ToNumber를 적용하면 대부분 숫자 리터럴 규칙/구문과 비슷하게 작동한다. 변환이 실패하면 결과는 NaN이다. 한 가지 차이는 0이 앞에 붙는 0진수는 ToNumber에서 올바른 숫자 리터럴이라도 8진수로 처리하지 않는다는 점이다.

 

문자열 값에 대한 숫자 리터럴 문법과 ToNumber는 아주 세밀하고 미묘한 뉘앙스의 차이가 있어 더 이상 언급하지 않는다.

 

객체(그리고 배열)는 일단 동등한 원시 값으로 변환 후 그 결괏값(아직 숫자가 아닌 원시 값)을 앞서 설명한 ToNumber 규칙에 의해 강제변환 된다.

 

동등한 원시 값으로 바꾸기 위해 ToPrimitive 추상 연산 과정에서 해당 객체가 valueOf() 메서드를 구현 했는지 확인한다. valueOf()를 쓸 수 있고 반환 값이 원시 값이면 그대로 강제변환하되, 그렇지 않을 경우 toString()을 이용하여 강제변환한다.

어찌해도 원시 값으로 바꿀 수 없을 땐 TypeError 오류를 던진다.

 

ES5 부터는 [[Prototype]]null인 경우 대부분 Object.create(null)를 이용하여 강제변환이 불가능한 객체를 생성할 수 있다. 다음 코드를 참고하자

 

var a = {
  valueOf: function () {
    return "42";
  },
};

var b = {
  toString: function () {
    return "42";
  },
};

var c = [4, 2];
c.toString = function () {
  return this.join(""); // "42"
};

Number(a); // 42
Number(b); // 42
Number(c); // 42
Number(""); // 0
Number([]); // 0
Number(["abc"]); // NaN

참고

  • You Don't Know JS ( 한빛 미디어 )
728x90

댓글