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

JS中为何用getter/setter而非直接访问属性?附示例对比

Getter/Setter vs 直接访问属性:哪种方案更优?

很棒的问题!很多刚接触JavaScript存取器的开发者都会有这个疑惑——毕竟在简单场景下,直接访问属性确实看起来更省事。咱们先把你给出的两个等价代码示例摆出来,再详细分析:

两个等价代码示例

示例1:使用Getter/Setter

const menu = { 
  _courses: { 
    appetizers: [], 
    mains: [], 
    desserts: [], 
  }, 
  get appetizers() { 
    return this._courses.appetizers; 
  }, 
  set appetizers(appetizer) { 
    this._courses.appetizers = appetizer; 
  } 
} 
menu.appetizers.push(['food']); 
console.log(menu.appetizers);

示例2:直接访问属性

const menu = { 
  _courses: { 
    appetizers: [], 
    mains: [], 
    desserts: [], 
  }, 
} 
menu._courses.appetizers.push(['food']); 
console.log(menu._courses.appetizers);

你提到这两段代码功能完全等价、输出结果一致,并且觉得第二种直接访问的方式更易懂,想知道为什么Getter/Setter会被认为是更优方案,以及针对这个具体示例哪种方式更好。


为什么Getter/Setter被视为更优方案?

Getter和Setter的核心价值在于封装性和可维护性,虽然在这个极简示例里显得多余,但在实际业务的复杂场景下,它们的优势会非常明显:

  • 封装内部实现细节:假设未来你需要修改appetizers的存储逻辑——比如从直接存在_courses对象里,改成从后端接口动态获取,或者把存储结构从数组改成Map。如果用了Getter/Setter,你只需要修改存取器的内部代码,所有外部调用menu.appetizers的地方完全不需要改动;但如果是直接访问menu._courses.appetizers,所有用到这个路径的代码都得跟着改,维护成本会指数级上升。
  • 添加数据校验与约束:你可以在Setter里加入校验逻辑,确保存入的数据符合预期,比如:
    set appetizers(newAppetizers) {
      if (!Array.isArray(newAppetizers)) {
        throw new Error("开胃菜列表必须是数组类型");
      }
      // 还可以进一步校验数组中的每个元素是否为合法的菜品名称
      const isValid = newAppetizers.every(item => typeof item === 'string');
      if (!isValid) {
        throw new Error("每个开胃菜必须是字符串类型");
      }
      this._courses.appetizers = newAppetizers;
    }
    
    这样就能避免错误的数据被存入,而直接访问属性的话,任何人都可以随意修改_courses.appetizers,没有任何约束,很容易引入bug。
  • 统一对外接口:不管内部数据结构怎么变化,外部始终通过menu.appetizers这个统一接口来访问和修改数据,代码风格更一致,也更符合面向对象编程的封装原则——把内部私有细节(比如_courses这个下划线开头的属性,通常约定为内部私有,不应该直接访问)隐藏起来,只暴露安全、可控的接口。

针对你的示例,哪种方式更好?

在这个超简单、无扩展需求的场景下,直接访问属性确实更简洁易懂,完全没问题——毕竟代码越少,心智负担越低。但如果这个menu对象是一个会被多人维护、或者未来有扩展需求的模块(比如要添加菜品校验、修改存储方式等),那强烈建议使用Getter/Setter:

  • 它能给未来的迭代留有余地,避免后续重构时大规模改动调用代码;
  • 也能明确区分对外暴露的公共接口和内部私有属性,让代码的可读性和可维护性更高。

简单总结:短期小项目、一次性脚本,直接访问更高效;长期维护、需要扩展的代码,Getter/Setter是更稳健的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:41:46