剂量值未通过验证

Dosage values are not passing correct through validation

本文关键字:验证      更新时间:2023-09-26

我正在编写一个函数来验证一个数字是否是有效剂量。有效剂量由0到100(包括范围)的值给出。它看起来很简单,但有三个条件:

  • 该值不是必需的,因此空值应返回true
  • 末尾可以有一个可选的"%"百分号
  • 小数位数也是可选的

我认为我已经接近了最终的功能,但有一次测试我的功能失败了,我不明白为什么:

function checkDosage(originalValue) {
    var validDosage, isNumeric,
        value = originalValue;
    isNumeric = function(num) {
        return !isNaN(num);
    }
    // take off percent sign if exists
    if (value.slice(-1) == '%') {
        value = value.slice(0, -1);
    }
    // get numeric value
    value = parseFloat(value);
    // check if it is really a number
    isNumeric = isNumeric(value);
    // conditional for dosage
    validDosage = value >= 0 && value <= 100;
    // treatment
    if (!originalValue || isNumeric && validDosage) {
        return true; // valid
    }
    return false; // invalid
}
checkDosage('');       // true
checkDosage('0');      // true
checkDosage('%');      // true
checkDosage('-1%');    // false
checkDosage('10.5%');  // true
checkDosage('10%%');   // true ??????? THIS SHOULD BE FALSE
checkDosage('100%');   // true
checkDosage('101%');   // false

谢谢你抽出时间。

问题在于使用parseFloat,它会丢弃它找到的任何尾随字符。

相反,使用Number(string),它将返回一个数字或值NaN(不是数字)。然后,可以用对内置函数isNaN 的调用来替换isNumeric函数

您只是在检查字符串是否以%结尾。您没有检查是否正好有零个或一个% s。

在你的百分比符号逻辑中,你可以这样做:

if (value.slice(-1) === '%') {
  value = value.slice(0, -1);
  if (value.slice(-1) === '%') {
    return false;
  }
}

这将截断百分号。如果字符串末尾仍有百分号,则表示存在多个%。因此,验证失败,返回false

EDIT:您现有的逻辑没有捕获到双%的原因是,如果字符串是10%%,并且您截断了最后一个%,那么它将是10%。如果你拨打parseFloat('10%'),你会得到10,它通过了你的isNumeric测试。