【问题标题】:How does one prevent NaN as return value of various number value calculations?如何防止 NaN 作为各种数值计算的返回值?
【发布时间】:2021-10-29 09:25:04
【问题描述】:

我是 Javascript 新手,我正在尝试进行计算,该计算会根据输入输入的数字而变化。 然而,这些函数将输出转换为 NaN,所以我想知道是否可以将 NaN 转换为正常数字(以便我可以将 hUeCalc 和 massCalc 添加在一起并将其显示为数字)使用,或者我是否必须使用另一个选项进行计算。

也许 switch 和 case 可能是一个选项,但我不太确定它们是否会产生我需要的效果。

在下面的代码中,您可以看到按下按钮时执行的功能。现在,当我单击激活函数 calc 的按钮时,我在 tax.innerHTML 中得到 NaN 而不是数字。

提前致谢。

function calc() {
    let hubraum = Number(hubraumComponent.value);
    let emission = Number(emissionComponent.value);
    let masse = Number(masseComponent.value);

    let hUeCalc = Number(function (){
        if (Diesel.checked == true) {
            ((Math.ceil((hubraum/100)))*9.5)+((emission-95)*2);
        }
        else if (Benzin.checked == true) {
            ((Math.ceil((hubraum/100)))*2)+((emission-95)*2);
        };
    });

    let masseCalc = Number(function (){
        let masseValue;
        if (masse <= 2000) {
           masseValue = (Math.ceil((masse/200)*5.625));
        }
        else if (masse >= 3000) {
            masseValue =(Math.ceil((masse/200)*6.01));
        }
        else if (masse >= 3500) {
            masseValue = (Math.ceil(masse/200)*6.39);
        };
    });
    // let masseValue = (Math.ceil (masse/200));

    let berechnung = (hUeCalc + masseCalc);
    tax.innerHTML = (berechnung) + "€";
    console.log('Calc has been done');
    console.log('hubraum value is ' + hubraum);
    console.log('emission value is ' + emission);
    console.log('masse value is ' + masse);
    console.log('hubraumcalc value is ' + hUeCalc);
    console.log('massecalc value is ' + masseCalc);
}

这里还有 HTML 以防你想看到激活所有这些的按钮

<div class="input-field-second-calc" onclick="calc()">
                <input type="button" class="btn btn-outline-primary" value="berechnen">
                <br>
                <a id="tax"></a>
            </div>

【问题讨论】:

  • 当它返回 NaN 时,这意味着不是数字。所以不,你不能把它转换成数字。但是,在大多数情况下,这意味着您在操作中的某处获得了非数字值。您可以尝试记录值以查看问题的确切位置
  • 不确定你想用Number(function (){做什么。你能添加你打电话给calc()的方式吗?
  • Number.NaN 尽管它的名称是一个数字值(typeof Number.NaN 等于 'number'),但可以用它来计算。不利的一面是,NaN 参与的每个计算结果也将是NaN
  • 顺便说一句,哪个计算是正确的...谈论嵌套括号...(Math.ceil((masse/200)*factor)); vs (Math.ceil(masse/200)*factor)?

标签: javascript function numbers calculation


【解决方案1】:

你需要在你的两个函数中返回一个值!

当你这样做时:

let hUeCalc = Number(function (){
    if (Diesel.checked == true) {
        ((Math.ceil((hubraum/100)))*9.5)+((emission-95)*2);
    }
    else if (Benzin.checked == true) {
        ((Math.ceil((hubraum/100)))*2)+((emission-95)*2);
    };
})

您基本上是说请将函数的返回值转换为数字并将其分配给hUeCalc。但是作为函数什么都不返回。它正在尝试将 undefined 转换为数字。结果是 NaN。

同样如此:

 let masseCalc = Number(function (){
    let masseValue;
    if (masse <= 2000) {
       masseValue = (Math.ceil((masse/200)*5.625));
    }
    else if (masse >= 3000) {
        masseValue =(Math.ceil((masse/200)*6.01));
    }
    else if (masse >= 3500) {
        masseValue = (Math.ceil(masse/200)*6.39);
    };
});

顺便说一句:

if (masse <= 2000) {
   masseValue = (Math.ceil((masse/200)*5.625));
}
else if (masse >= 3000) {
    masseValue =(Math.ceil((masse/200)*6.01));
}
else if (masse >= 3500) {
    masseValue = (Math.ceil(masse/200)*6.39);
};

您永远不会到达最后一个else if,就像我们尝试使用 3700 一样。第一个 if 不匹配,第二个 if 3700 大于 3000。需要颠倒两个 else if 的顺序。

您还需要为 2000 到 3000 之间的数字添加 else (如果它是可接受的值)

【讨论】:

  • 是的,其他的事情是有道理的 XD 谢谢^^
【解决方案2】:

代码重构应将当前计算分别分为提供/实现单个专用计算函数的部分和使用正确值(包括有效的后备值)调用计算的部分,以防某些条件无法满足。

另外我建议修改命名。不要混用语言。跳过德语部分,因为大部分代码(包括日志记录)都是用英文命名和注释的。

function getCalculatedHUeValue(displacement, emission, fuelFactor) {
  return (Math.ceil(displacement / 100) * fuelFactor) + ((emission - 95) * 2);
}
function getCalculatedMassValue(mass, massFactor) {
  return Math.ceil(mass / 200 * massFactor);
}

function calc() {
  const displacement = Number(displacementComponent.value);
  const emission = Number(emissionComponent.value);
  const mass = Number(massComponent.value);

  const hUeCalc = getCalculatedHUeValue(displacement, emission,
    (Diesel.checked && 9.5) ||
    (Benzin.checked && 2) ||
    0 // default/fallback value needs to be provided/known.
  );
  const massCalc = getCalculatedMassValue(mass,
  
    ((mass <= 2000) && 5.625) ||
    ((mass >= 3500) && 6.39) ||
    ((mass >= 3000) && 6.01) ||
  
    // what is the factor for the uncovered
    // mass range in between 2001 and 2999?

    0 // this fallback value has to be provided/known.
  );
  const result = (hUeCalc + massCalc);

  tax.innerHTML = (result + "€");

  console.log('Calculation is done');
  console.log('displacement value is ' + displacement);
  console.log('emission value is ' + emission);
  console.log('mass value is ' + mass);
  console.log('hUeCalc value is ' + hUeCalc);
  console.log('massCalc value is ' + massCalc);
}

【讨论】:

  • 通常我只用英语工作,但这是一个私人练习,所以为了能够专注于任务,我决定用德语做几句话。如果我会努力让其他人看到,那么我永远不会调用函数 hUeCalc。
  • @Heroann ... 明白了。对我来说,更重要的是在当前接受的答案中作为解决方案呈现的 IIFE(您的旧代码作为立即调用的函数表达式)被重构为明确定义的任务(纯计算和将参数传递给计算的条件部分) .因此,很清楚将什么类型传递给这样的函数以及期望返回什么。更重要的是,通过分离的布尔逻辑,很明显必须提供一个最终数字值,这在原始代码中完全被遗漏了。
  • @Heroann ... 还有一件事,质量相关因子的计算方式必须通过切换优先级来解决。但即便如此,在 2001 年和 2999 年之间(包括)还有一个未覆盖的范围?还需要提供一个数值,否则适合上述范围的质量的最终结果将是NaN
【解决方案3】:

如果您尝试以下代码,我认为它应该可以工作。正如你所看到的,如果你想使用一个函数来赋值一个值,这个函数必须返回一些东西,如果它没有,就没有要赋值的值。你还需要确保函数被执行,如果你不这样做,let hUeCalc = function(){} 只是成为函数标识符。

function calc() {
    let hubraum = Number(hubraumComponent.value);
    let emission = Number(emissionComponent.value);
    let masse = Number(masseComponent.value);

    let hUeCalc = Number(function (){
        if (Diesel.checked == true) {
            return ((Math.ceil((hubraum/100)))*9.5)+((emission-95)*2);
        }
        else if (Benzin.checked == true) {
            return ((Math.ceil((hubraum/100)))*2)+((emission-95)*2);
        };
    }());

    let masseCalc = Number(function (){
        let masseValue;
        if (masse <= 2000) {
            return masseValue = (Math.ceil((masse/200)*5.625));
        }
        else if (masse >= 3000) {
            return masseValue =(Math.ceil((masse/200)*6.01));
        }
        else if (masse >= 3500) {
            return masseValue = (Math.ceil(masse/200)*6.39);
        };
    }()); // using () right after the function makes it so it get excecuted immediately
    // let masseValue = (Math.ceil (masse/200));

    let berechnung = (hUeCalc + masseCalc);
    tax.innerHTML = (berechnung) + "€";
    console.log('Calc has been done');
    console.log('hubraum value is ' + hubraum);
    console.log('emission value is ' + emission);
    console.log('masse value is ' + masse);
    console.log('hubraumcalc value is ' + hUeCalc);
    console.log('massecalc value is ' + masseCalc);
}

【讨论】:

  • 是的!谢谢已经工作了。好吧,试图将函数变成一个数字是一种绝望的尝试,让它成为一个数字而不是一个 NaN XD
  • 它变成了一个 NaN,因为你不能把一个函数变成一个数字。还要确保你阅读了我下面关于 else if 的答案。
  • 我做了也改了^^
  • @Heroann ...上面的代码仍然存在未为未满足的条件提供值的问题...我怀疑如果涉及边缘情况它实际上会正确计算
  • @JarneKompier ...上述建议的解决方案甚至不是一个持久的补丁,因为它没有解决过于复杂的问题(容易出错,OP只是通过寻求帮助来证明它)并且重复(5 次计算而不是 2 次),因此难以阅读且难以维护代码。
猜你喜欢
  • 2016-04-09
  • 1970-01-01
  • 2011-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 2014-07-22
  • 2018-05-11
相关资源
最近更新 更多