Search code examples
javascripthtmlnullnan

What is the standard way to check a variable is initialised as a number in javascript?


I am trying to test a variable to ensure [a] it is initialised and [b] and is a number before supplying the number as an argument. I have tried to do this using two functions noNil(i) and noNan(i). It makes sense to find if a variable is initialised before testing if it is a number. But it makes little difference which function is called first. The first alert reports undefined while the second alert report nothing. What is the standard way to check a variable is initialised as a number in pure javascript ?

e.g.

    var i;

    noNil();
    alert(i);
    noNaN(i);
    alert(i);

    function noNil(i) {
      if (i === undefined){
      let i = -1;
        return i;
      }
    }

    function noNan(i) {         
      if (isNaN(i)) {
      let i = 30;   
        return i;
      }
    }

Clarification

A bit of context might help. The variable is defined in 5 ways; 0 to 4 select colours from an array. If it is undefined none of the colours is selected.

    let family    = ["yellow", "red", "lime", "cyan","magenta"];
    ...
    ctx.fillStyle = family[i];

Solution

  • Use typeof i === 'number' to determine whether the value is of the JS number type.

    const checkNumber = i => { if( typeof i !== 'number') throw new Error('Supplied argument is not a number!'); return i;};
    
    function sum(a, b){
      return checkNumber(a) + checkNumber(b);
    }
    
    console.log(sum(2, 2));
    
    var i;
    
    console.log(sum(i, 2));

    About your use case with selecting colors, you could avoid bothering with numbers:

    let family    = ["yellow", "red", "lime", "cyan","magenta"];
    family[i] && (ctx.fillStyle = family[i]);
    

    But the main question could be why you are ending up with i not being a number of a proper index of your color array...

    If you want to check strings the topic suddenly becomes much more complex (I don't even cover all cases here like scientific notation):

    var i;
    
    function isNumber(i) {
      return typeof i === 'number';
    }
    
    function isNumerish(i) {
      return !isNaN(parseFloat(i));
    }
    
    function isStringNumber(i) {
      return /^-?\d*\.?\d+$/.test(i);
    }
    
    const checks = [[i, isNumber], [-.5, isNumber], ['-.5a', isNumerish], ['-.5a', isStringNumber], ['-.5', isStringNumber]];
    
    for(const [num, fn] of checks){
      console.log(num, fn.name, fn(num));
    }