我正在尝试使用getter和setter编写一个简单的对象,我不完全确定这个代码是否正确,我在使用下划线的实例时也有点困惑。我得到的当前错误是menu.addDishToCourses is not a function
,但控制台记录了这顿饭,将其属性显示为一个函数。是什么给了什么?
let menu = {
_courses: {
_appetizer: [],
_main: [],
_dessert: [],
get appetizers() {
return this._courses.appetizer;
},
set appetizers(appetizerInput) {
this._courses.appetizer = appetizerIn;
},
get mains() {
return this._courses.main;
},
set mains(mainsInput) {
this._courses.main = mainsInput;
},
get desserts() {
return this._courses.dessert;
},
set desserts(dessertsInput) {
this._courses.deseserts = dessertInput;
},
get courses() {
return {
appetizers: this._courses.appetizer,
mains: this._courses.main,
desserts: this._courses.dessert,
};
},
addDishToCourses(courseName, dishName, dishPrice) {
const dish = {
name: dishName,
price: dishPrice,
};
this._courses[courseName].push(dish);
},
getRandomDishFromCourse(courseName) {
const dishes = this._courses[courseName];
const RandomIndex = Math.floor(Math.random() * dishes.length);
return dishes[RandomIndex];
},
generateRandomMeal() {
let appetizer = this.getRandomDishFromCourse('appetizer');
let main = this.getRandomDishFromCourse('main');
let dessert = this.getRandomDishFromCourse('dessert');
let totalPrice = appetizer.price + main.price + dessert.price;
return `You order and appetizer ${appetizer.name},${main.name} and a main dish ${main.price} and a dessert ${dessert.price}. Total price was $${totalProice}. `;
},
}
};
menu.addDishToCourses('_appetizer', 'pepperoni', 5.43);
menu.addDishToCourses('_mains', 'steak', 18.0);
menu.addDishToCourses('_dessert', 'pie', 3.5);
答案 0 :(得分:1)
您进行此设置menu
的方式有一个属性:_courses
。 menu.addDishToCourses()
不是函数,但menu._courses.addDishToCourses()
是函数。
我认为你应该后退一步,询问为什么要使用getter和setter,而不仅仅是访问属性和函数。如果需要吸气剂或定位器,则应该是显而易见的。如果这个变得更大,维护真的很难。
话虽如此,如果您想继续使用当前方案,只需将menu
上要调用的功能放在menu
上:
let menu = {
addDishToCourses(courseName, dishName, dishPrice) {
const dish = {
name: dishName,
price: dishPrice,
};
this._courses[courseName].push(dish);
},
get appetizers() {
return this._courses._appetizer;
},
_courses: {
_appetizer: [],
_main: [],
_dessert: [],
}
}
menu.addDishToCourses('_appetizer', 'pepperoni', 5.43);
console.log(menu.appetizers)

答案 1 :(得分:0)
您有一个范围问题。 getter和setter方法中的this
引用_courses
的{{1}}属性,而不是menu
对象本身。
您可能希望设计类似于以下内容的menu
对象:
menu

至于下划线命名的属性go,它只是一个用于命名私有变量的JavaScript约定(因为你将访问那些面向公众的getter和setter方法)。将下划线实际上做任何事情。
答案 2 :(得分:0)
一些快速点(其中一些已在各种评论中提及):
下划线是 约定 的隐私,并且无法实际执行隐私。该状态 仍可直接访问菜单用户 。
在我看来,使用具有可公开访问属性的getter / setter是徒劳的。 getter / setter的目的是在访问状态时强制执行合同,以便您可以在以后更改内部实现细节,而不会影响模块的用户。如果他们可以直接访问和改变您的状态,那么getter / setter就会变得混乱,因为您无法知道模块用户是否已经篡改了隐含的隐私约定。
有一些方法可以在JavaScript中将您的州设为私有(请参阅下面的一个选项)。但是,如果真正的私有状态并不重要,那么为了清楚起见,只需删除getter / setter和下划线。只需创建一个带有一些额外函数的普通对象,这些函数可以为操作该状态添加真正有用的行为。
现在,如果您确实想要保持菜单状态为私有并控制对它的访问,那么这是一个如何做到这一点的示例。对我而言,这种方法更清晰,更易于阅读,并且实际上实现了您的目标。
library(zoo)
mmavg <- function(x) {
len <- length(x)
sorted <- sort(x)
c(min=mean(sorted[2:4]), max=mean(sorted[(len-3):(len-1)]))
}
cbind(val=Data, rollapplyr(Data, 10, mmavg, fill=NA))
# val min max
# 8 NA NA
# 2 NA NA
# 9 NA NA
# 7 NA NA
# 8 NA NA
# 8 NA NA
# 9 NA NA
# 8 NA NA
# 4 NA NA
# 9 6.333333 8.666667
# 9 6.333333 9.000000
# 7 7.333333 9.000000
# 2 6.000000 8.666667
# 5 5.333333 8.666667
# 2 3.666667 8.666667
# 2 2.666667 8.666667
# 1 2.000000 8.000000
# 9 2.000000 8.333333
# 9 2.000000 9.000000
# 7 2.000000 8.333333
&#13;