VSCode扩展配置对象处理异常:before为1但before1为0的原因排查
VS Code配置对象传入第三方库后的异常行为分析
问题场景
开发VS Code扩展时,通过vscode.workspace.getConfiguration(extName).get(settingName)[name]获取到如下配置对象:
{ "docs": {"wrap": true, "around": 1, "indent": " "} }
将其中的docs对象传入第三方库后,该库执行以下代码:
if (!('before' in opts)) opts.before = ('around' in opts) ? opts.around : 0; if (!('before1' in opts)) opts.before1 = ('before' in opts) ? opts.before : 0;
执行后出现异常:opts.before === 1,但opts.before1 === 0。
原因分析
问题的核心在于VS Code返回的配置对象是被冻结的。为了避免扩展意外修改全局配置,VS Code会对getConfiguration()返回的对象调用Object.freeze()进行冻结处理。
当第三方库尝试给opts.before赋值时:
- 如果代码运行在严格模式下,会直接抛出
TypeError; - 如果是非严格模式,赋值操作会静默失败——
opts.before并不会被成功添加到对象中,'before' in opts的结果依然是false。
这就导致后续判断'before' in opts时为false,opts.before1因此被赋值为0。而你看到的opts.before === 1,通常是调试器的误导:调试器会显示赋值语句执行后的临时值,但实际对象并没有新增该属性。
解决办法
- 拷贝配置对象后传入:在将配置对象传给第三方库前,先做一次浅拷贝或深拷贝,解除冻结状态:
// 浅拷贝(适用于单层结构的配置) const unfrozenOpts = {...yourConfigObject}; // 深拷贝(适用于嵌套结构的配置) const unfrozenOpts = JSON.parse(JSON.stringify(yourConfigObject)); - 修改第三方库逻辑:如果有权限修改第三方库代码,可以改为返回新对象而非直接修改传入的参数,或者先检查对象是否可扩展后再进行赋值。
内容的提问来源于stack exchange,提问作者Phrogz
相关产品推荐
相关产品推荐

