首页 > 解决方案 > 无法读取未定义的属性“toFixed”

问题描述

我是 javascript 的初学者,希望能得到一些帮助

问题:

皮特的披萨店以价格合理的美味披萨而闻名。编写一个程序,帮助皮特计算订单的价格。确保您添加了 13% 的税,并且您的答案显示到小数点后 2 位。Pete的定价如下:

  • 小份:奶酪 5 美元 + 每个配料 0.75 美元
  • 中等:奶酪 7 美元 + 每种配料 1.00
  • 大份:奶酪 10 美元 + 每个额外配料 1.25 美元

Pete 只有 10 种可用的浇头,所以如果员工输入的浇头超过 10 种,那肯定是有错误。假设他们想要 10 个。

这是我的代码和错误:


let order, cost, small, medium, large, topping;
order = prompt("What size pizza?");
order = parseInt(prompt("How many additional toppings?"));

if (small==5.00){
  cost = 5.00 * 1.13;
  document.write ("$5.65");
}
else {
  topping>=1==0.785+topping
}
document.write("Total $"+cost+topping.toFixed(2));

最后一行 ( document.write("Total $...) 有这个错误:

未捕获的类型错误:无法读取未定义的属性“toFixed”

标签: javascriptundefinedtypeerrortofixed

解决方案


回复:“toFixed未定义”

  • 此错误是因为您从未为topping变量赋值。
  • 在 JavaScript 中topping也是如此。undefined
  • 而且您不能使用任何方法/属性/undefined变量成员,因此您所做的与 相同undefined.toFixed(2),这是不正确的。

其他一切:

  • let当您可以使用时,您正在使用const
  • 您声明变量的时间远远早于它们实际使用的时间(尤其是topping),这使得跟踪变得更加困难(并且也使得快速确定变量(如topping)何时处于有效状态变得更加困难。
  • 您有未分配的(因此是“ undefined”)变量:smallmediumlarge
  • 你正在覆盖你的order变量。
  • prompt您没有对您的和parseInt调用执行任何输入无效和错误处理。
  • 使用前导零时应始终指定radix参数,parseInt否则将导致字符串被解释为八进制而不是十进制。
    • 您还需要使用isNaN来验证是否parseInt成功。
  • 您正在使用==IEEE 浮点number值(例如),由于浮点的工作方式(原样)small == 5.00,这将意外失败。 5.000000001 == 5.00false
    • 出于同样的原因,您不应该在 JavaScript 中使用非整number数值来表示货币/货币值。相反,您应该将货币值表示为整数美分,并且仅在程序的“表示”部分将它们格式化为十进制数。
  • 这个表达topping>=1==0.75+topping是没有意义的——它实际上也没有做任何有用的事情。我不确定它到底是什么意思...
  • 你永远不应该使用document.write- 它是 1990 年代的遗留物,不应该被添加。textContent相反,您可以通过设置元素的 (例如<output>)或.valuea 的属性来在页面上显示文本<textarea><input type="text">(不要忘记制作它readonly)。
  • "Total $" + cost + topping.toFixed(2)在连接字符串与将数字相加时, 您的表达式对 JavaScript 的类型强制做出了错误的假设。
    • 相反,您需要首先执行算术加法作为带括号的表达式,或使用新变量来存储中间结果),然后应将其格式化为字符串并将其与“Total”部分连接。
    • 还可以考虑使用该Intl库(它内置于 JavaScript)来格式化货币值,而不是硬编码美元符号。

正确的实现:

我已将解决方案的逻辑分解为子功能,而入口点是pizzaProgram功能。

您可以通过单击“运行片段”并回答提示来直接运行该程序。

const PIZZA_SIZE = {
    'SMALL' : 1,
    'MEDIUM': 2,
    'LARGE' : 3
};

function pizzaProgram() {
    
    const pizzaSize = promptForPizzaSize();
    if( !pizzaSize ) return;
    
    const toppings = promptForToppingCount();
    if( !toppings ) return;

    // cost is in integer cents.
    const costBeforeTax = getPizzaCostBeforeTax( pizzaSize, toppings );
    const costAfterTax  = costBeforeTax * 1.13;

    const costFormatted = "Total cost: $ " + ( costAfterTax / 100 ).toFixed(2);
    alert( costFormatted );
}

// Returns either a PIZZA_SIZE value, or null
function promptForPizzaSize() {
    
    // Loop until valid input is received:
    while( true ) {
        
        const inputSize = prompt("What size pizza? Enter 1 for Small, 2 for Medium, or 3 for Large. Or enter 'q' to cancel.");
        switch( inputSize ) {
        case '1': return PIZZA_SIZE.SMALL;
        case '2': return PIZZA_SIZE.MEDIUM;
        case '3': return PIZZA_SIZE.LARGE;
        case 'q': return null;
        }
    }
      
}

// Returns either an integer or null
function promptForToppingCount() {
    
    // Loop until valid input is received:
    while( true ) {
        
        const inputToppings = prompt("How many additional toppings? Or enter 'q' to cancel.");
        if( inputToppings === 'q' ) return null;

        const toppings = parseInt( inputToppings, /*radix:*/ 10 );
        if( !isNaN( toppings ) && toppings >= 0 && toppings <= 10 )
        {
            return toppings;
        }
    }
}

// Returns integer USD cents
function getPizzaCostBeforeTax( size, toppings ) {

    // Preconditions:
    if( typeof size     !== 'number' ) throw new Error("size must be a number");
    if( typeof toppings !== 'number' ) throw new Error("toppings must be a number");

    // Logic:

    if( size === PIZZA_SIZE.SMALL ) {
        return 500 + ( 75 * toppings );
    }
    else if( size === PIZZA_SIZE.MEDIUM ) {
        return 700 + ( 100 * toppings );
    }
    else if( size === PIZZA_SIZE.LARGE ) {
        return 1000 + ( 125 * toppings );
    }
    else {
        throw new Error("This branch should never be taken.");
    }
}

pizzaProgram();


推荐阅读