表单里填价格,用户输入了12abc,后端算出来是12,账对不上。前端校验写的是isNaN取反,而isNaN会先做类型转换,空字符串转成0,空格也转成0,问题就出在这。

typeof只认number类型

typeof x等于number时对NaN也返回true,因为NaN的类型就是number。所以它只能排除字符串和对象,不能证明是有效数字。input里的值永远是字符串,用typeof判会全部为false。

Number.isFinite是目前最稳的

Number.isFinite(12) // true; Number.isFinite(NaN) // false; Number.isFinite(Infinity) // false; Number.isFinite('12') // false

它不做类型转换,字符串一律false。要允许字符串,先Number(v)再判。ES2015之前用全局isFinite,那个会转换类型,空字符串照样通过。

isNaN和Number.isNaN的区别

  • isNaN:先转数字再判,空字符串为false,null为false,undefined为true。
  • Number.isNaN:只有真正的NaN才为true,不做转换。
  • parseInt:parseInt(12abc,10)返回12,它是解析不是校验,别拿来判合法性。

要正整数就这么写

用正则判断纯数字串,再Number(v)大于0排除0。要小数用带可选负号和小数点的正则。Number.isInteger(Number(v))也能判整数,但它接受1e3这种科学计数法。

结论:判断值本身用Number.isFinite,判断字符串用正则加Number双重校验。别再用isNaN单独兜底,空字符串和小数点都能混过去。