You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS使用setter返回undefined,getter触发TypeError问题求助

解决JavaScript Getter/Setter实现今日菜单的问题

问题描述

尝试用JavaScript的getter和setter实现简易「今日菜单」程序,需求是从对象数组中随机获取食物名称和对应价格。但遇到以下问题:

  • 调用menu.priceToCheck与menu.mealToCheck时返回undefined
  • 调用getter todaysSpecial时触发错误:TypeError: Cannot convert undefined or null to object
  • 预期输出示例:The menu today has pizza for only 13 dollars
  • 不使用getter/setter的代码可正常运行

问题代码

let menu = {
  
    _meals : [
        {"burger": 14},
        {"mouzakas": 12},
        {"pasta": 10},
        {"pizza": 13},
    ],

    
    set meal(mealToCheck) {
      if (typeof mealToCheck === 'string') {
        let random_index = Math.floor(Math.random() * this._meals.length);
        let new_obj = this._meals[random_index];
        return new_obj = mealToCheck;
        
      }
      else {
        return 'input error';
      }
      
    },
    
    set price(priceToCheck) {
      if (typeof priceToCheck === 'number') {
        
        return Object.values(this.new_obj) = priceToCheck;
      }
      else {
        return 'input error';
      }
     
    },
    
    get todaysSpecial() {
     if (Object.keys(this.new_obj) !== '' && Object.values(this.new_obj) !== 0) {
        return  'The menu today has ' + Object.keys(this.new_obj) + ' for only ' + Object.values(this.new_obj) + ' dollars';

      }
     else {
       return 'Meal or price was not set correctly!'
      }
   }
    
    
    
    
    };
    
    console.log(menu.priceToCheck);
    console.log(menu.mealToCheck) ;
    console.log(menu.todaysSpecial);

补充:可正常运行的无Getter/Setter代码

meals = [
    {"burger": 14},
    {"mouzakas": 12},
    {"pasta": 10},
    {"pizza": 13},
];


let random_index = Math.floor(Math.random() * meals.length);

let obj = meals[random_index];

console.log(obj[0]);

console.log('The menu today has ' + Object.keys(obj) + ' for only ' + Object.values(obj) + ' dollars');



console.log(Object.keys(obj));
console.log(Object.values(obj));

错误原因分析

  1. Setter使用逻辑错误:
    • Setter的作用是给对象属性赋值,不是直接调用获取值,你定义的setter是meal和price,但却调用了不存在的mealToCheck、priceToCheck属性,自然返回undefined。
    • Setter不应该返回值,它的职责是修改对象状态,而不是返回结果。
  2. 实例属性未正确存储:
    • 你在setter里定义的new_obj是局部变量,不是menu对象的实例属性,导致getter中this.new_obj为undefined,调用Object.keys()时触发类型错误。
  3. Price setter冗余且逻辑错误:
    • 价格是菜品对象的固有属性,不需要单独设置,随机选中菜品后就能直接获取价格,单独的price setter完全没必要,且代码中Object.values(this.new_obj) = priceToCheck是非法赋值逻辑。
  4. Getter中的判断逻辑错误:
    • Object.keys(this.new_obj)返回的是数组,和空字符串''比较永远不成立;Object.values(this.new_obj)返回的也是数组,和0比较也不正确。

修复后的代码

let menu = {
    _meals: [
        {"burger": 14},
        {"mouzakas": 12},
        {"pasta": 10},
        {"pizza": 13},
    ],
    _selectedMeal: null, // 存储选中的菜品对象

    // 用setter触发随机选餐逻辑,参数可作为触发标识(比如传入任意字符串触发)
    set meal(trigger) {
        if (typeof trigger === 'string') {
            const randomIndex = Math.floor(Math.random() * this._meals.length);
            this._selectedMeal = this._meals[randomIndex];
        } else {
            console.error('输入错误:请传入字符串触发随机选餐');
        }
    },

    get todaysSpecial() {
        if (!this._selectedMeal) {
            return '请先触发随机选餐!';
        }
        const mealName = Object.keys(this._selectedMeal)[0];
        const mealPrice = Object.values(this._selectedMeal)[0];
        return `The menu today has ${mealName} for only ${mealPrice} dollars`;
    }
};

// 正确调用setter:给meal属性赋值触发随机选餐
menu.meal = 'random';
console.log(menu.todaysSpecial);

修复说明

  1. 新增实例属性存储选中菜品:添加_selectedMeal来保存随机选中的菜品对象,确保getter能访问到有效数据。
  2. 修正Setter逻辑:
    • Setter仅负责触发随机选餐并存储结果,不再错误返回值。
    • 通过给menu.meal赋值(传入任意字符串)来触发选餐逻辑,符合setter的使用规范。
  3. 移除冗余的Price Setter:价格从选中的菜品对象中直接提取,不需要单独设置。
  4. 优化Getter判断与取值:
    • 先判断是否已选中菜品,避免undefined错误。
    • 直接提取数组第一个元素(因为每个菜品对象只有一个键值对),让结果更清晰。
  5. 修正调用方式:不再调用不存在的mealToCheck/priceToCheck,而是通过给menu.meal赋值触发逻辑,再调用menu.todaysSpecial获取结果。

内容的提问来源于stack exchange,提问作者Gizmapps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 15:09:13