JS Optional Chaining调用异常:对undefined调用apply抛出TypeError
异常产生原因
- 按照ES2020规范,可选链在函数调用场景
?.()的正确逻辑为:先判断左侧的调用目标是否为null/undefined,如果是则直接短路返回undefined,既不会执行函数调用逻辑,也不会对传入的参数(包括展开语法传入的...args、fn2、fn3)做任何求值操作。 - 你遇到的报错本质是运行环境的实现不符合规范:不管是旧版本的JS引擎(比如Chrome 80以下、Node.js 14以下的早期版本)、有bug的转译工具(比如低于7.8.0版本的Babel可选链插件)、或者错误实现的可选链polyfill,在处理带展开语法参数的可选调用时,没有先做左侧判空短路,而是直接生成了等价于对
undefined调用Function.prototype.apply的底层代码,因此抛出该TypeError。
修复方案
- 优先升级运行环境:使用符合ES2020规范的正式版环境,比如Node.js 14.0+、Chrome 80+、Firefox 74+、Safari 13.1+,这类环境可以直接正确运行你的示例代码,不会触发异常。
- 若必须兼容旧环境,手动编写判空逻辑替代可选链的直接调用,避免依赖旧的可选链转译:
- 最稳妥的写法是先判断目标值是否为函数,再执行调用,该写法兼容所有JS环境:
console.log(typeof fn1 === 'function' ? fn1(...args, fn2, fn3) : undefined)
- 最稳妥的写法是先判断目标值是否为函数,再执行调用,该写法兼容所有JS环境:
- 若使用Babel转译,将
@babel/plugin-proposal-optional-chaining升级到7.8.0及以上版本,该版本已经修复了带展开参数的可选调用的转译bug。
内容的提问来源于stack exchange,提问作者Wenfang Du
相关产品推荐
相关产品推荐

