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?
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');