[트러블 슈팅]isNaN 와 Number.isNaN

Jinny·2024년 11월 3일
0

트러블 슈팅

목록 보기
1/1
post-thumbnail
  hasNumbers() {
    return this.parseCarNames.some((carName) => /\d/.test(carName));
  }

이렇게 하면
'1'
1
rice1

모두 true 값을 인식이 된다.


이번 우아한테크코스 FE 프리코스 3을 진행하면서 다음을 배운 것을 정리한다 :)

로또 게임 프로그램을 만들고 있는데, 그 중 1부터 45까지 숫자 중 보너스 번호 한 자리를 입력받는 기능을 구현하였다. 이 기능을 예외 처리를 하려니 숫자가 아닌 '#' 같은 문자나 '십삼'과 같은 문자열을 예외로 처리를 하려고 처음에는 isNaN을 다음과 같이 작성했다.

Before

isValidNumberBonusNumber() {
  return !isNaN(this.bonusNumber);
}

그런데 이렇게 작성하니 ESLint 오류가 발생했다.

오류 메시지

Unexpected use of 'isNaN'. Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnaneslintno-restricted-globals

처음에는 간단하게 앞에 Number만 붙이면 되겠다고 생각해서 !isNaN을 !Number.isNaN으로 변경했다.

After

  isValidNumberBonusNumber() {
    return !Number.isNaN(this.bonusNumber);

하지만, 문제가 생겼다.

어떤 문제였을까?

바로 isNaN과 Number.isNaN의 동작 방식 차이 때문이다. 먼저 헷갈릴 수 있으니 !를 빼고 로그를 찍어 보았다.

    console.log('isNaN(this.bonusNumber) :', isNaN(this.bonusNumber))
    console.log('Number.isNaN(thi.sbonusNumber) :', Number.isNaN(this.bonusNumber))

이렇게 로그를 찍어 보면 다음과 같이 출력된다.



그리고 다음과 같이 !를 붙여서 찍어보았다.

 console.log('!isNaN(this.bonusNumber) :', !isNaN(this.bonusNumber))
    console.log('!Number.isNaN(this.bonusNumber) :', !Number.isNaN(this.bonusNumber))

출력 결과는 다음과 같다.



결과를 보면, !isNaN은 #과 십삼에 대해서는 false로 뜨고, 숫자로 입력한 13에만 true 값이 나온다. 하지만 !Number.isNaN은 #, 십삼, 13 모두 true로, 숫자가 맞다고 한다. 뭐가 잘못된 걸까?

isNaN()의 동작방식

  1. 입력된 값을 숫자로 변환한다.
  2. 숫자로 변환된 값이 NaN인지 확인한다.
  3. NaN인 경우 -> true 반환 / 숫자이면 flase반환
  • NaN은 Not-a-Number의 약자로, 주로 숫자로 변환할 수 없는 계산 결과나 값이 숫자 가 아님을 나타내는 특수한 값
예시
isNaN(1);      // false
isNaN('1');    // false
isNaN('일');   // true
isNaN('#');    // true

문자열 포함해서 숫자인지 파악하려면

!isNaN(1);      // true
!isNaN('1');    // true
!isNaN('일');   // false
!isNaN('#');    // false

이렇게 쓰면 되지만, 문제는 ESLint 오류가 난다는 점이다. 그렇다고 무작정 Number.isNaN()을 사용하면 아래와 같은 결과가 나온다.

Number.isNaN()예시

Number.isNaN(1);        // false
Number.isNaN('1');      // false
Number.isNaN('일');     // false
Number.isNaN('#');      // false

이렇게 하면 문자열이 숫자인지 여부를 제대로 파악할 수 없다.

해결 방법: Number()와 함께 사용하기

Number()로 값을 숫자로 변환한 후, Number.isNaN()을 사용하면 정확한 결과를 얻을 수 있다.

Number.isNaN(Number(1));        // false
Number.isNaN(Number('1'));      // false
Number.isNaN(Number('일'));     // true
Number.isNaN(Number('#'));      // true

숫자인지 알기 위해서는 반대로 작성하면 된다.

!Number.isNaN(Number(1));       // true
!Number.isNaN(Number('1'));     // true
!Number.isNaN(Number('일'));    // false
!Number.isNaN(Number('#'));     // false

Number.isNaN()의 동작 방식

  1. 먼저 숫자 타입 (number)인지 확인한다.
  2. 숫자 타입이라면 NaN 여부를 확인한다.
    • NaN인 경우 -> true 반환
    • NaN이 아닌 경우 -> false 반환

예시

Number.isNaN(NaN);                 // true
Number.isNaN(Number('abc'));       // true
Number.isNaN(42);                  // false
Number.isNaN('NaN');               // false
Number.isNaN(undefined);           // false
Number.isNaN('Hello');             // false
Number.isNaN(true);                // false
Number.isNaN(Number('Hello'));     // true

예를 들어:

  • Number.isNaN(1) -> 숫자 타입이지만 NaN이 아니므로 false 반환.
  • Number.isNaN('1') -> 숫자 타입이 아니므로 바로 false 반환.

이처럼 isNaN()과 Number.isNaN()의 차이를 명확히 이해하고 사용해야 한다.

profile
세상을 이롭게 하는 프론트엔드 개발자 Jinny

0개의 댓글