首页 > 解决方案 > 我如何让这段代码打印出这个输出。我不断为 .buyproduct 定义不确定

问题描述

我收到此错误,我不确定如何修复它。我想获得我在下面发布的预期输出,但需要使用点链。有人可以帮忙吗?

.buyProduct({ item: 'bud light', quantity: '3'})
^                

TypeError: Cannot read property 'buyProduct' of undefined
    var products = [];
   class Product {
   constructor(productName, amount, cost) {
       this.productName = productName,
        this.amount = amount,
        this.cost = cost
    }

    buyProduct(product){
       products.push(product);
    }
    deleteProduct(str){
       var found = products.find(function(element){
           return (element.productName).toLowerCase() == 
    str.toLowerCase();
       })
       if(found)
       {
           if(found.amount>1)
           {
               var foundIndex = 
    products.findIndex(x=>x.productName.toLowerCase() === 
    str.toLowerCase());
               products[foundIndex].amount = found.amount-1;

           }
           else
           {

 products.splice(products.findIndex(item=>item.productName.toLowerCase() 
        === str.toLowerCase()),1)
           }
       }
      }
       sumPrice(str,num){
       var foundIndex = 
      products.findIndex(x=>x.productName.toLowerCase() === 
    str.toLowerCase());
       if(foundIndex>=0)
       {
           products[foundIndex].cost = products[foundIndex].cost + num;
       }
      }
     sumTotal() {
       var total = 0;
       for (var obj in products)
       {
           total+= obj.amount*obj.cost;
       }
       return total;
      }
      write() {
       var total = 0;
       for (var obj in products)
       {
           console.log('Item: '+obj.productName + ' | 
    Quantity:'+obj.amount+' | Price:'+obj.cost);
           total+= obj.amount*obj.cost;
       }
       console.log('$'+total);

      }
      }


                .buyProduct({ item: 'jameson', quantity: '1'})

                .buyProduct({ item: 'bud light', quantity: '3'})

                .buyProduct({ item: 'corona', quantity: '4'})

                .buyProduct({ item: 'beer', quantity: '1'})

                .sumPrice('tequila', 5.99)

                .deleteProduct('corona')

                .sumPrice('beer', 5.04)

                .sumTotal()

                .write

预期输出:

项目:詹姆士| 数量: 1 | 价格:不适用

项目:芽光| 数量:3 | 价格:不适用

项目:电晕 | 数量:3 | 价格:5.99 美元

项目:啤酒| 数量: 1 | 价格:1.04 美元

总计:19.01 美元

标签: javascriptecmascript-6

解决方案


当你执行像 object.methodA().methodB() 这样的东西时会发生什么?.methodB 在任何 object.methodA() 返回时被调用。例如,以下代码将遇到与您相同的问题:

const dog = {
    bark: function(){
        console.log('The dog barks at the mail man!')
    },
    chase: function(){
        console.log('The dog chases the mail man!')
    }
}

dog.bark().chase(); //Uncaught TypeError: Cannot read property 'chase' of undefined

我们可以通过执行以下操作来解决此问题:

const dog = {
    bark: function(){
        console.log('The dog barks at the mail man!')
        return dog;
    },
    chase: function(){
        console.log('The dog chases the mail man!')
        return dog;
    }
}

dog.bark().chase(); // The dog barks at the mail man! The dog chases the mail man!

要修复您的代码,您需要每个方法返回一个 Product 实例。最简单的方法可能是返回this关键字,正如 cvgn 建议的那样,因为this对应于调用方法的对象:

var products = [];
class Product {
   constructor() {

    }

    buyProduct(product){
       products.push(product);
       return this; // return object used in calling .buyProduct, `prod` in example below.
    }
}

const prod = new Product();

prod.buyProduct({ item: 'bud light', quantity: '3'})
    .buyProduct({ item: 'jameson', quantity: '1'});
console.log(products); 
//output will be an array of the product objects

编辑:为什么 sumPrice 方法可能会给你一个错误的解释:

尝试将以下日志添加到 sumPrice 方法,并注意记录的内容:

console.log('STR: ', str);
console.log('NUM: ', num);
console.log('PRODUCT :', products[0]);
console.log('PRODUCT NAME: ', products[0].productName);
/* ... */
//STR:  jameson, NUM:  3, PRODUCT : {item: "jameson", quantity: "1"}, PRODUCT NAME:  undefined

您传递给 .buyProduct 的对象是{item: 'jameson', quantity: '1'}; 它没有“productName”属性,因此您无法访问它。请注意,您将遇到与 .cost 相同的问题,因为您的对象也没有“成本”属性:

products[foundIndex].cost = products[foundIndex].cost + num;
//products[foundIndex].cost  -> undefined; undefined + num -> NaN

您可以通过将 .productName 切换为 .item 并在 .buyProduct 调用中声明成本属性来在短期内解决此问题:

   /* ... */
    sumPrice(str,num){
        var foundIndex = 
            products.findIndex(x=>x.item.toLowerCase() === 
                str.toLowerCase());
    /* ... */

const prod = new Product;
prod.buyProduct({ item: 'jameson', quantity: '1', cost: 0}).sumPrice('jameson', 3.99)
console.log(products);

但是,我怀疑您的根本问题是与 JavaScript 构造函数有些混淆,因为您并没有真正在代码中使用它。基本上,构造函数在您使用new关键字时运行:

var products = [];
class Product {
   constructor(productName, amount, cost) {
       this.productName = productName,
        this.amount = amount,
        this.cost = cost
    }
}

const prod = new Product('jameson', 1, 3.99);

console.log(prod);
//Product {productName: "jameson", amount: 1, cost: 3.99}

但是,您的 buyProduct 方法在推送到 products 数组时不使用该对象;它只是使用您传入的任何对象作为参数。此外,要以现在的方式使用构造函数,您需要为每个项目(const jameson = new Product('jameson'...) const pepsi = new Product('pepsi'...)等)创建一个新的类实例。

我的建议是阅读 class 关键字和工厂函数,因为它们似乎是你大部分困惑的根源。这是一篇很好的文章:https ://medium.com/javascript-scene/javascript-factory-functions-with-es6-4d224591a8b1


推荐阅读