开发者问题收集

无法读取未定义的属性“toFixed”

2021-10-01
2404

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

问题:

pete's pizza place is famous for great pizza at reasonable prices. Make a program that will help pete compute the price on the orders. make sure you add on 13% tax and that you display the answer to 2 decimal places. Pete's pricing is as follows:

  • small: $5 for cheese + 0.75 per topping
  • medium: $7 for cheese + 1.00 for each topping
  • Large: $10 for cheese + 1.25 for each additional topping

Pete only has 10 available toppings, so if an employee types in more than 10, there must be some mistake. Assume they wanted 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 $... ) 出现此错误:

Uncaught TypeError: Cannot read property 'toFixed' of undefined

2个回答

回复:“ toFixed 未定义”

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

其他所有内容:

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

这是导致您特别询问的错误的实际问题:

topping>=1==0.75+topping

这会将 topping1 == 0.75 + topping 进行比较,如果 topping 大于或等于该值,则计算结果为 true 。它不会设置 topping ,并且它也永远不会为真。

您可能想要这样的东西:

topping = 0.75 * topping;

您还在 topping 上调用 toFixed ,而不是(您可能打算)调用整个值。这应该是这样的:

document.write("Total $" + (cost+topping).toFixed(2));

您的代码中还有许多其他问题,这些问题仍然会导致它无法正常工作。例如,您正在检查 small == 5.00 是否永远不会为真,因为您从未设置过该变量。您使用值 order 表示披萨的大小和配料的数量,然后再也不会使用该值。(无论如何, order 都是这个变量的错误名称,因为它不是顺序,而是大小或配料的数量。)

最重要的是风格问题,例如何时应使用 const 或是否应使用 document.write — 如果您犯了某些错误,您的代码仍会正常工作,但它不符合专业惯例。

这看起来像一个家庭作业问题,而 Stack Overflow 并不是为您完成家庭作业的服务。所以我没有提供所有这些问题的解决方案。但这应该能让您更接近答案。

kindall
2021-10-01