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

为何JavaScript中getter/setter触发栈溢出后代码仍能正常运行?

问题解析:为什么同名属性与get/set未触发递归栈溢出

你的代码里根本没触发定义的get msg()和set msg()方法,自然不会出现递归栈溢出问题,核心原因在于实例自身的数据属性屏蔽了原型上的访问器属性:

  • 类中的msg = 'Hello'是实例公共字段,当创建instance实例时,这条语句会直接在实例对象自身上添加一个名为msg的数据属性,初始值为'Hello'。
  • 而你定义的get msg()和set msg()是挂载在ClassWithGetSet类的原型对象上的访问器属性。
  • JavaScript的属性查找规则是:访问对象属性时,优先查找实例自身的属性,找到就直接返回或赋值;只有当实例自身没有该属性时,才会沿着原型链向上查找对应的访问器或数据属性。

所以你的代码实际执行流程是:

  1. console.log(instance.msg):直接读取实例自身的msg属性,输出'Hello',完全没触发原型上的getter。
  2. instance.msg = 'Sandra':直接修改实例自身的msg属性值为'Sandra',也没触发原型上的setter。
  3. 第二次console.log(instance.msg):还是读取实例自身修改后的msg值,输出'Sandra'。

如果想让get/set访问器生效,你需要避免在实例自身添加同名数据属性,通常的做法是使用内部私有字段(比如用下划线前缀命名),然后在访问器中操作这个字段:

class ClassWithGetSet{
    _msg = 'Hello'; 
    get msg(){
        return this._msg;
    }

    set msg(x){
        this._msg = `Hello ${x}`;
    }
}

const instance = new ClassWithGetSet(); 
console.log(instance.msg); // 输出 'Hello'
instance.msg = 'Sandra'; 
console.log(instance.msg); // 输出 'Hello Sandra'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:35:05