ES6类中与属性同名的setter函数调用时机及原理问询
为什么JavaScript类的setter会在构造函数赋值时触发?
核心原因:类的setter是原型上的访问器属性
你定义的set fullName()并不是实例自身的属性,而是被挂载到PersonCL.prototype上的访问器属性。用class语法写setter/getter时,JavaScript引擎会自动把它们加到类的原型对象上,而非每个实例单独拥有。
赋值时的查找逻辑
当构造函数里执行this.fullName = fullName时,JavaScript会按以下流程处理:
- 先在当前实例(
this指向的新创建对象)上查找fullName属性,此时实例刚初始化,还没有这个属性; - 接着沿着原型链往上找,找到
PersonCL.prototype上的fullName,发现它是一个带有setter的访问器属性; - 直接调用这个setter方法,把传入的
fullName参数传给setter的name形参; - setter逻辑执行后,会把合法的名字存入
this._fullName——这才是实例上真正新增的普通属性。
为什么不直接给实例加属性?
访问器属性的优先级高于普通属性。只要原型链上存在对应属性的setter,赋值操作就会优先触发setter,而非直接在实例上创建新的普通属性。除非你后来手动给实例添加fullName普通属性,后续赋值才会覆盖setter的优先级(但你的代码里不会出现这种情况,因为setter并未给this.fullName赋值)。
验证方法
你可以在控制台打印原型的属性描述符,直观看到setter的存在:
console.log(Object.getOwnPropertyDescriptors(PersonCL.prototype)); // 输出结果中,fullName对应的属性会包含set和get方法,而非普通属性的value字段
创建实例后,打印实例自身的属性,只会看到_fullName和birthYear,没有fullName:
const person = new PersonCL('John Doe', 1990); console.log(Object.keys(person)); // 输出 ["_fullName", "birthYear"]
内容的提问来源于stack exchange,提问作者zonley
相关产品推荐
相关产品推荐

