Node.js对象定义使用扩展运算符导致this访问属性为undefined的原因
该问题的核心原因
这是旧版本V8引擎的实现Bug,仅出现在 Node.js 15.x 及更早、Chrome 90 之前的运行环境中,完全不符合 ECMAScript 标准规定的对象字面量行为,新版本环境运行你提供的代码会正常输出ab。
具体Bug触发逻辑
旧版V8处理带扩展运算符...的对象字面量时,错误地拆分了属性挂载流程:
- 扩展运算符之前定义的所有常规属性,会被临时写入一个过渡对象,不会直接挂载到最终生成的对象上
- 执行扩展操作合并传入对象的属性后,后续定义的属性(包括扩展后的常规属性、getter/setter访问器)才会被写入最终对象
- 存储在过渡对象里的扩展前属性,没有被正确拷贝到最终对象上,直接被丢弃
你给出的示例中,prop定义在...obj之前,因此被错误丢弃,this.prop返回undefined,而prop2定义在扩展之后,能正常挂载,最终输出结果就是undefinedb。
为什么扩展放首尾就正常
- 扩展放最开头时,不存在"扩展之前的自定义常规属性",所有你写的属性都在扩展之后,不会被拆分丢弃
- 扩展放最后时,所有你写的自定义属性(包括getter)都在扩展之前,全部会被直接挂载到最终对象上,再执行扩展合并,不会出现属性丢失
如果要避免该问题,升级Node.js到16.x及以上版本即可,新版本V8已经修复了该Bug,对象字面量属性会严格按照书写顺序依次挂载到最终对象上。
内容的提问来源于stack exchange,提问作者dor272
相关产品推荐
相关产品推荐

