You need to enable JavaScript to run this app. Safari中尾调用优化(TCO)未生效?尾递归阶乘测试报栈溢出
优惠活动
大模型
产品
解决方案
定价
更多

Safari中尾调用优化(TCO)未生效?尾递归阶乘测试报栈溢出

问题根因

你遇到的问题是遗漏了ES6规范规定的TCO(尾调用优化)生效的核心前提,并非Safari的实现存在缺陷。

TCO生效的强制要求

  • 必须启用严格模式(Strict Mode)
    这是ES6规范明确的TCO触发必要条件:非严格模式下为了兼容旧代码遗留的arguments对象、函数caller属性,引擎必须保留外层函数的完整栈帧,无法将其销毁复用为尾调用的栈帧,因此直接禁用TCO优化。你当前的测试代码没有任何严格模式声明,默认运行在非严格模式下,36000次递归直接撑爆调用栈,抛出RangeError。

    如果在Safari控制台直接粘贴代码测试,必须手动添加严格模式声明,控制台默认运行在非严格模式环境。

  • 尾调用位置必须符合规范
    你写的三元表达式分支中的factorial调用本身符合尾位置要求:函数最终返回值就是该调用的返回结果,没有额外运算操作,这部分没有问题。

正确测试代码调整方案

在代码顶部添加严格模式声明即可触发TCO:

'use strict'
function factorial(n, r = 1n) {
  return (n <= 1) ? r : factorial(n - 1n, n * r)
}
console.log(factorial(36000n))

如果使用ES模块加载代码(<script type="module">),模块默认处于严格模式,无需额外添加'use strict'声明,直接运行原递归逻辑即可正常执行,不会触发栈溢出。

常见误区

ES兼容性表中标注的Safari支持TCO,指的是实现了规范要求的严格模式下的TCO能力,而非非严格模式下的兼容优化,这是多数开发者踩坑的核心原因。

内容的提问来源于stack exchange,提问作者kornieff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.04 07:36:03