Javascript 使用函数正确编写getter和setter
我试图用getter和setter编写一个简单的对象,我不完全确定代码是否正确,我对在实例中使用下划线也有点困惑。我当前遇到的错误是Javascript 使用函数正确编写getter和setter,javascript,Javascript,我试图用getter和setter编写一个简单的对象,我不完全确定代码是否正确,我对在实例中使用下划线也有点困惑。我当前遇到的错误是menu.addDishToCourses不是一个函数,而是控制台记录膳食,将其属性显示为一个函数。有什么好处 let menu = { _courses: { _appetizer: [], _main: [], _dessert: [], get appetizers() {
menu.addDishToCourses不是一个函数
,而是控制台记录膳食,将其属性显示为一个函数。有什么好处
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);
你有一个范围问题
此
在getter和setter方法中是指菜单
的属性,而不是菜单
对象本身
您可能希望设计类似以下内容的菜单
对象:
let菜单={
_课程:{
_开胃菜:[],
_main:[],
_甜点:[],
吃开胃菜{
把这个还给我
},
获取main(){
把这个还给我
},
吃甜点{
把这个还给我
}
},
获取课程(){
返回{
开胃菜:这个,
梅因:这个,
甜点:这个,
};
},
添加DishToCourses(课程名称、dishName、dishPrice){
让盘子={
姓名:dishName,,
价格:价格,,
};
//console.log(this._课程[courseName]);
这个._课程[课程名称].推(碟);
}
};
菜单。添加菜肴(“开胃菜”、“辣香肠”,5.43);
菜单。添加菜肴(“主菜”、“牛排”,18.0);
菜单。添加餐前菜(“甜点”、“馅饼”3.5);
控制台.日志(菜单.课程)
设置菜单的方式有一个属性:\u课程
menu.adddishcourses()
不是函数,而是menu.\u courses.adddishcourses()
是函数
我认为您应该退一步,问问为什么要使用getter和setter,而不仅仅是访问属性和函数。如果需要一个getter或setter,这应该是显而易见的。如果这变得更大,它将很难维持
话虽如此,如果要继续当前方案,只需将要从菜单
调用的函数置于菜单
:
let菜单={
添加DishToCourses(课程名称、dishName、dishPrice){
常数盘={
姓名:dishName,,
价格:价格,,
};
这个._课程[课程名称].推(碟);
},
买开胃菜{
把这个还给我。_课程。_开胃菜;
},
_课程:{
_开胃菜:[],
_main:[],
_甜点:[],
}
}
菜单。添加菜肴(“开胃菜”、“辣香肠”,5.43);
console.log(菜单.开胃菜)
几个要点(其中一些已在各种评论中提到):
下划线是根据惯例规定的隐私,不做任何实际强制隐私的事情。该状态对于菜单用户仍然是可直接访问的
在我看来,使用具有公共可访问属性的getter/setter是徒劳的。getter/setter的目的是在访问state时强制执行约定,以便以后可以更改内部实现细节,而不会影响模块的用户。如果他们可以直接访问并改变您的状态,那么getter/setter就是杂乱无章的,因为您无法知道模块用户是否遵守了您隐含的隐私约定
有几种方法可以用JavaScript将您的状态设置为私有(请参见下面的一个选项)。然而,如果真正的私有状态并不重要,那么为了清晰起见,只需删除getter/setter和下划线即可。只需创建一个普通对象,其中包含一些额外的函数,这些函数为操纵该状态添加了真正有用的行为
现在,如果你真的想让你的菜单保持私有状态,并控制对它的访问,这里有一个例子可以说明如何做到这一点。对我来说,这种方法更干净、更容易阅读,并且实际上实现了您的预期
const menu=(函数菜单(){
//此状态是私有范围
常数课程={
开胃菜:[],
main:[],
甜点:[]
};
//这些函数是私有范围的,除非公开(见下文)
函数addDish(课程、名称、价格){
课程[课程]。推送({name,price});
}
函数getDishesByCourse(课程){
返回课程[课程];
}
//这就是你向外界透露的
返回{addDish,getDishesByCourse};
})();
菜单。添加菜肴(“开胃菜”、“辣香肠”,5.43);
console.log(menu.getDishesByCourse(“开胃菜”)代码>JavaScript根本不是我的强项,但下划线用于getter/setter映射到的内部属性。尚未深入研究,但addDishToCourses似乎有“作为家长的课程而不是菜单”menu
有一个属性,\U courses
。其他所有内容都被定义为其中的一员,因此您需要编写菜单。\课程..
。此外,下划线是一种惯例,有些人用它来表示私有的东西。不要求使用本公约。最后,要定义一个方法,实际上需要创建一个属性并为其分配一个函数,如:addDishToCourses:function(courseName,dishName,dishPrice){…}
。呸,你比我快了几秒钟,哈哈。应该注意的是,下划线只表示私有字段/方法,在这种情况下,它们不是真正需要的?谢谢,先生。下划线把我弄糊涂了,我现在明白了。