Node.js中Class的Getter/Setter使用及JSON序列化问题咨询
关于Node.js类中Setter写法的问题解答
嘿,这个问题问到点子上了,我来给你把事儿说透:
首先直接给结论:把setter里的下划线去掉,写成set name(name) { this.name = name; }这种写法完全不合理,会直接触发致命错误。
为什么会出问题?
当你执行myPerson.name = "Saul"时,JavaScript会自动调用name属性的setter方法。而如果setter里写的是this.name = name,这相当于再次给name属性赋值,又会触发同一个setter方法——如此循环往复,直到调用栈超出JavaScript的最大限制,直接抛出RangeError: Maximum call stack size exceeded的栈溢出错误。
简单说就是:你在setter里又调用了自己,陷入无限递归死循环了。
回到你最初的痛点:JSON序列化显示_name而非name
你原来用_name作为存储变量的写法,是前端圈约定俗成的封装方式,但确实会导致JSON.stringify()输出_name字段。要解决这个问题,最直接的方案是给类添加自定义的toJSON()方法,手动控制序列化的结果:
class Person { constructor() { this.id = 'id_1'; this._name = ''; // 约定俗成的私有存储变量 } set name(name) { this._name = name; } get name() { return this._name; } // 自定义JSON序列化逻辑 toJSON() { return { id: this.id, name: this.name // 调用getter获取name的值,而非直接取_name }; } } // 测试效果 const myPerson = new Person(); myPerson.name = "Saul"; console.log(JSON.stringify(myPerson)); // 输出: {"id":"id_1","name":"Saul"}
如果你想用更严谨的私有变量(外部完全无法直接访问),可以使用ES6+的私有字段语法(#前缀),配合toJSON()同样能解决问题:
class Person { #name; // 真正的私有字段,外部无法直接访问 constructor() { this.id = 'id_1'; } set name(name) { this.#name = name; } get name() { return this.#name; } toJSON() { return { id: this.id, name: this.name }; } }
总结
- 绝对不要在
name的setter里直接给this.name赋值,会触发无限递归栈溢出; - 要解决JSON序列化显示
_name的问题,自定义toJSON()方法是最可靠的方案; - 追求更严谨封装的话,推荐使用ES6私有字段配合getter/setter。
内容的提问来源于stack exchange,提问作者Makan
相关产品推荐
相关产品推荐

