我收到此错误,我不确定如何解决。我想获得我在下面发布的预期输出,但需要使用点链。有人可以帮忙吗?
.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
答案 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