我如何获得此代码以打印输出。我一直对.buyproduct不确定

时间:2019-02-16 22:22:36

标签: javascript ecmascript-6

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

.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

预期输出:

项目:jameson |数量:1 |价格:不适用

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

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

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

总计:$ 19.01

1 个答案:

答案 0 :(得分:1)

当执行诸如object.methodA()。methodB()之类的东西时会发生什么?在任何对象上调用.methodB。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的实例。如cvgn所建议的,最简单的方法可能是返回this关键字,因为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遇到同样的问题,因为您的对象也没有“ 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