javascriptnumberstypeofisnan

How do you easily check whether a Variable is number or not in JavaScript?


I am not a JavaScript developer, but I just want to know the right way to check a variable contain a number or not. After a couple analysis I reached below solution. Is it correct way?

function calculation(n1,n2 , ...numbers) {

  let validateNumber = (num) => {
    if(num !== num)
      return 0;
      else
    return typeof num === 'number' ? num : 0;
  }

  let sum =0;
  for(n of numbers){
    sum += validateNumber(n);
  }
  console.log(sum);
} 

calculation(5,6,7,'gg','',null, NaN, undefined,  null,8,9,5.4,10);

Please check the 'validateNumber' arrow function.


Solution

  • First version =>
    -- simply use isNaN() : sum+(isNaN(val)?0:Number(val)

    Second version (asked in comment here) =>
    -- just use a strict comparison. to get only numeric type values.

    const calculation =(...numbers)=>  // (n1,n2 , ...numbers)=>
      numbers.reduce((sum,val)=>
        sum + (Number(val)===val ? val : 0)  // sum+(isNaN(val)?0:Number(val))
        , 0);
    
    console.log( calculation(5,6,7,'gg','',null, NaN, undefined,  null,8,9,5.4,'10') )

    For more clarity, here it is a table showing the execution of the test according to the different possible types

    const
      testFunction = val => Number(val)===val
    , values =
      [ { v: 123,       display: `123`,       expected: true  }
      , { v: '123',     display: `"123"`,     expected: false }
      , { v: NaN,       display: `NaN`,       expected: false }
      , { v: undefined, display: `undefined`, expected: false }
      , { v: null,      display: `null`,      expected: false }
      ]
    , tBody = document.querySelector('table > tbody')
      ;
    let score = 0
      ;
    for (let {v, display, expected} of values)
      {
      let
        TR  = tBody.insertRow()
      , res = testFunction(v)
        ;
      score += expected===res ? 1 : 0
      TR.insertCell().textContent = display
      TR.insertCell().textContent = expected
      TR.insertCell().textContent = res
      TR.insertCell().className   = expected===res ? 'ok' : 'bad'
      }
    document.querySelector('table >tfoot td:nth-of-type(2)')
      .textContent = `${score} / ${values.length}`
    table { font-family: Arial, Helvetica, sans-serif;border-collapse: collapse;margin: 0 1em; }
    td    { padding: .2em .8em;border: 1px solid darkblue; } 
    thead,tfoot {  background-color: #84a4ce;text-transform: capitalize; }
    caption     { padding: .3em;caption-side: bottom;font-size: .8em; }
    .ok:before,.bad:before { font-weight: bold;font-size: 1.2em; }
    .ok:before  { color: green;content: '\2713'; }
    .bad:before { color: red;  content: '\2718'; }
    <table>
      <caption>( Number(val)===val ) ?</caption>
      <thead>
        <tr> <td>val</td><td>expected</td><td colspan="2">result</td> </tr>
      </thead>
      <tbody></tbody>
      <tfoot>
        <tr> <td colspan="3">score</td><td>0/0</td> </tr>
      </tfoot>
    </table>