正确编写具有功能的getter和setter

时间:2018-04-17 19:26:41

标签: javascript

我正在尝试使用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);

3 个答案:

答案 0 :(得分:1)

您进行此设置menu的方式有一个属性:_coursesmenu.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)

一些快速点(其中一些已在各种评论中提及):

  1. 下划线是 约定 的隐私,并且无法实际执行隐私。该状态 仍可直接访问菜单用户

  2. 在我看来,使用具有可公开访问属性的getter / setter是徒劳的。 getter / setter的目的是在访问状态时强制执行合同,以便您可以在以后更改内部实现细节,而不会影响模块的用户。如果他们可以直接访问和改变您的状态,那么getter / setter就会变得混乱,因为您无法知道模块用户是否已经篡改了隐含的隐私约定。

  3. 有一些方法可以在JavaScript中将您的州设为私有(请参阅下面的一个选项)。但是,如果真正的私有状态并不重要,那么为了清楚起见,只需删除getter / setter和下划线。只需创建一个带有一些额外函数的普通对象,这些函数可以为操作该状态添加真正有用的行为。

  4. 现在,如果您确实想要保持菜单状态为私有并控制对它的访问,那么这是一个如何做到这一点的示例。对我而言,这种方法更清晰,更易于阅读,并且实际上实现了您的目标。

    
    
    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;
    &#13;
    &#13;