You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在try/catch中重声明函数参数会抛出ReferenceError?

为什么在try/catch块内重声明函数参数会抛出ReferenceError?

这确实是个容易让人摸不着头脑的问题,我来一步步拆解背后的原因:

先看没有try/catch的情况

当你直接在函数作用域里重声明参数时:

function foo(bar) {
  const bar = 123; // SyntaxError: Identifier 'bar' has already been declared
}
foo(456);

这时候抛出SyntaxError是符合预期的——因为函数参数bar已经在函数作用域中被声明了,而const(和let一样)不允许在同一作用域内重复声明同一个标识符,这个错误在代码解析阶段(编译时)就会被检测到。

再看try/catch包裹的情况

你的示例代码:

function foo(bar) {
  try {
    console.log(bar); // 这里会触发ReferenceError
    const bar = 123;
  } catch(err) {
    console.log(err) // ReferenceError: bar is not defined
  }
}
foo(456);

这里的核心是**块级作用域和暂时性死区(TDZ)**的影响:

  • try块是一个独立的块级作用域,当你在里面写const bar = 123时,这个bar的声明会被提升到try块的顶部,但会进入暂时性死区——也就是在声明语句执行之前,这个变量已经存在但无法被访问。
  • 当执行到console.log(bar)时,JavaScript引擎会优先在当前的try块作用域中查找bar,它确实找到了这个被提升的const声明(虽然还没初始化),所以不会去外层函数作用域找那个已经传入的bar参数。
  • 访问处于暂时性死区的变量,就会直接抛出ReferenceError,这时候代码还没执行到const bar = 123这一行,自然不会触发重复声明的SyntaxError。

简单来说,try块的块级作用域让内部的bar成为了一个全新的变量,只是它的暂时性死区导致你在声明前访问时,抛出了和预期不同的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:25:41