Search code examples
javascriptnumbersnan

NaN is allowing a combination of numbers and letters in this code


Why is NaN allowing a combination of numbers and letters in my code?

let gameIsStarted = false;
let guesses = [];

const startButton = document.getElementById('startButton');

startButton.addEventListener('click', function() {
  gameIsStarted = !gameIsStarted;

  if (gameIsStarted) {
    let n = 0;
    while (n <= 0) {
      n = Math.round(parseFloat(prompt('You have begun to play. What is the highest number you wish to be able to guess?')));
      if (isNaN(n)) {
        alert('That is not a number! Please enter a number.');
        n = 0;
      } else if (n < 1) {
        alert('Please enter a number 1 and above.');
        n = 0;
      }
    }

    let secretNum = secretNumber(n);
    guess(secretNum);

    function secretNumber(n) {
      return Math.floor(Math.random() * n) + 1;
    }

    function userGuess() {
      let guessValue = parseInt(prompt('What do you think the number is?'));
      guessValue = Math.round(guessValue);
      return guessValue;
    }

    function guess(secretNum) {
      let userGuessValue = userGuess();
      while (userGuessValue !== secretNum) {
        switch (true) {
          case isNaN(userGuessValue):
            alert('That is not a number!');
            userGuessValue = userGuess();
            break;
          case userGuessValue <= 0:
            alert('That number is too low. Pick a number that is at least 1.');
            userGuessValue = userGuess();
            break;
          case userGuessValue > n:
            alert('That number is not in range, try again.');
            userGuessValue = userGuess();
            break;
          case userGuessValue > secretNum:
            alert('No, try a lower number.');
            userGuessValue = userGuess();
            break;
          case userGuessValue < secretNum:
            alert('No, try a higher number.');
            userGuessValue = userGuess();
            break;
        }
      }
      alert('You got it!');
    }
  }
  gameIsStarted = false;
});

I have tried to use Metacharacters, I have asked everyone I know, but this will allow things like 13a or 17w. When I looked up the documentation on NaN, it worked there, so why is it not implementing in my code?


Solution

  • this will allow things like 13a or 17w

    The culprits are parseInt and parseFloat. They allow digits to be followed by other characters.

    console.log(parseInt('777$#@!*')); // 777
    console.log(parseFloat('123.56abcd')); // 123.56

    To validate the input strictly, use unary number coersion.

    console.log(+'777$#@!*'); // NaN
    console.log(+'777'); // 777
    console.log(+'123.56abcd'); // NaN
    console.log(+'123.56'); // 123.56

    Then you can perform other checks depending on what sort of number you need.

    function testNumber (value) {
        console.log('Value:', value);
        console.log('> integer OR fractional:', Number.isFinite(value));
        console.log('> integer:', Number.isInteger(value));
        console.log('> fractional:', Number.isFinite(value) && value != Math.floor(value));
    }
    
    testNumber(+'777$#@!*');
    testNumber(+'777.888');
    testNumber(+'1234');