typeof 123n === 'bigint'

구글 크롬 67 버전이 최근에 릴리즈 되었다. 많은 기능들이 추가 되었지만 이번 글에서는 BigInt에 대해서 알아보자.

BigInt?

BigInt는 자바스크립트(javascript)에 새로 추가된 기본 자료형(Primative type)이다. 자바스크립트의 기본 자료형은 총 7개이다. 원래(ES5)는 6개였지만 ES2015(ES6) 스펙에 Symbol 타입이 추가되면서 총7개가 되었다:
  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol (ECMAScript 6 에 추가됨)
  • Object
이제 BigInt가 추가되면서 총 기본 자료형은 8개가 된 것이다.
지금 크롬 브라우저 67(아직 다른 브라우저에선 지원되지 않는다.)을 키고 콘솔에 아래와 같이 입력 해보자:
typeof 123n;
이렇게 치면 'bigint'가 리턴되는 걸 볼 수 있을 것이다.
presentation
기본 자료형이 추가된다는 것은 별거 아니라고 생각 할 수도 있지만, 이것은 엄청난 변화이다. 이제 앞으로 우리는 어떤 값이 숫자인지 체크하기 위해 typeof variable === 'number' 만으로 우리가 원하는 결과를 만들어내지 못하는 경우가 생기는 것이다. 이제 앞으로 아래와 같이 체크를 해야 하는 경우가 머지않아 생길 것이다:
typeof variable === 'number' || typeof variable === 'bigint'

BigInt가 왜 필요한가?

자, 한번도 궁금해본적 없는(적어도 나는..) 것에 대해 알아보자. 자바스크립트에서 사용 할 수 있는 가장 큰 안전한(?) 정수는 몇일까?
그 값은 9007199254740991이다. 약 9000조... 사실지금까지 개발하면서 이렇게 큰 숫자를 다룰 일도 당연히 없었지만 궁금 하지도 않았다. 새로 추가된 BigInt를 알아보니 알게 된 사실이다. 이 안전한 정수는 Number객체에 상수로 정의 되어 있다. 지금 바로 브라우저 콘솔에 아래와 같이 입력해보자:
Number.MAX_SAFE_INTEGER
그럼 위에서 언급한 값을 얻을 수 있다.
presentation
자 그럼 Number.MAX_SAFE_INTEGER에 1을 더해보자. 9007199254740992가 리턴 되는 것을 알 수 있다. 다시 한번 1을 더해보자. 9007199254740993이 아닌 9007199254740992가 리턴 된다. 이렇게 되면 생기는 문제는 아래와 같다:
presentation
실제로 이러한 경우 때문에 node에서 버그를 발생 시키기도 한다.
이러한 문제(또는 한계) 때문에 BigInt가 추가 된것이다.

BigInt에 대해 알아보자.

아직 자바스크립트의 BigInt에 대한 자료가 없어서 크롬 블로그를 리뷰하는 수준의 글이 될 것 같으니 영문 자료 읽는 데 불편하지 않다면 크롬 공식 블로그 글을 확인하는 것을 추천한다.

BigInt를 선언하는 방법

BigInt를 선언하는 방법은 2가지이다. 숫자(number) 값 마지막에 n을 붙이는 방법과 BigInt 함수를 사용하여 선언하는 방법. 이렇게 두가지 이다:
100n === BigInt(100)

BigInt vs Number

기본적으로 BigInt는 Number와 같은 속성이라고 생각하면 된다. 0이 falsy 값이기 때문에 0n 역시 falsy 값이다:
if (0n) {   console.log('if'); } else {   console.log('else'); } // → logs 'else', because `0n` is falsy.
BigInt 역시 일반적인 연산자를 제공한다(+, -, *, **, /, &, |, &, <<, >>, ^ 와 음수(-)는 똑같이 지원한다. 단, 양수(+) BigInt는 지원하지 않는데, 그 이유는 asm.js의 규칙을 벗어나기 때문이다.

헷갈릴만한 상황들

대부분의 경우 Number와 크게 다르지 않기에 자칫 실수 할 수 있는 부분들을 집어보자.
예를들어, 123n + 10을 할 경우 값은 무엇일까? 이는 TypeError 에러를 일으킨다. 이유는 BigInt와 Number를 섞어서 연산 할 수 없기 때문이다. BigInt의 경우 Number 처럼 암시적인 형변환을 지원하지 않기 때문이다.
이 같은 이유(암시적인 형변환)을 지원하지 않기 때문에 BigInt('42')의 경우 SyntaxError를 BigInt(12.5)의 경우 RangeError를 뱉어낸다.
그렇다면 123 < 123n의 경우는 어떨까? 이것은 true다. ===, <, >= 연산의 경우 boolean을 리턴하기 때문에 암시적 형변환과 상관이 없다.

마무리

크롬 67에 새로 추가된 BigInt에 대해서 간단하게 알아 보았다. 이미 Stage 3에 속해있는 스펙이기 때문에 아무래도 ES2018 (ES9) 버전이나 이후 버전에는 표준 스펙에 포함되지 않을까 생각한다. 빠르게 변화하는 자바스크립트 환경에 맞춰 미리미리 준비한다는 마음으로 BigInt에 대해 알아보는 글이 되었으면 좋겠다.

관련글