为何JS类使用constructor和set/get方法时属性返回undefined
问题根因
- 你定义的属性读取器(
get方法)没有显式返回值,JavaScript中函数如果没有return语句,默认返回undefined,这是读取属性拿到undefined的直接原因 - 你定义的属性设置器(
set方法)仅打印了日志,没有将传入的值存储到实例的对应位置,值根本没有留存,自然无法正常读取 - 注意不能直接在
set方法内给同名属性赋值,否则会重复触发set方法导致递归栈溢出,常规方案是用带下划线前缀的属性作为实际存储的载体,和对外暴露的属性名区分开
修复后代码
class Animal { constructor(genus, name){ this.name = name; this.genus = genus; } // 名称属性设置器 set name(name){ console.log("you set name"); // 存储到下划线开头的属性,避免触发setter递归 this._name = name; } // 名称属性读取器 get name(){ console.log("you got name"); // 返回实际存储的属性值 return this._name; } // 属类属性设置器 set genus(genus){ console.log("you set genus"); this._genus = genus; } // 属类属性读取器 get genus(){ console.log("you got genus"); return this._genus; } makeNoise(noise = ""){ console.log(noise); } // 类静态方法 static _repr(){ return "Animal Class"; } }
运行测试结果
> let cat = new Animal("Feline", "Daisy"); you set name you set genus undefined > cat.name you got name 'Daisy' > cat.genus you got genus 'Feline'
如果需要更严格的属性封装,也可以使用ES2022新增的私有字段语法(用#开头的私有属性)来存储实际值,避免外部直接访问内部存储属性。
内容的提问来源于stack exchange,提问作者Timothy Pulliam
相关产品推荐
相关产品推荐

