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

为何这段JavaScript代码先输出undefined再抛出TypeError?

示例代码

function foo() {
  if (true) {
    function bar() { 
      console.log("bar");
    }
  } else {
    function qux() { 
      console.log("qux"); 
    }
  }
  
  console.log(qux); 
  qux(); 
}

foo();

输出结果

undefined
TypeError: qux is not a function
问题解答

为什么console.log(qux)输出undefined且未抛出ReferenceError?

这要从JavaScript的变量提升和旧引擎对块内函数声明的处理逻辑说起:

  • 当你在if/else这类块级语句里写函数声明时,引擎会把函数名(也就是qux这个标识符)提升到外层函数(foo)的作用域顶部,但不会同步提升函数定义。也就是说,foo作用域里提前存在了qux这个变量,初始值为undefined。
  • 因为代码里if (true)分支会执行,else分支完全不会进入,所以qux的函数定义从未被执行,它的值一直保持undefined。此时访问qux不会触发ReferenceError——毕竟这个变量已经存在于当前作用域中,只是没有赋值,所以console.log(qux)输出undefined。

为什么调用qux()会抛出TypeError?

qux的当前值是undefined,而undefined不属于函数类型,当你试图把它当作函数调用时,自然会抛出TypeError: qux is not a function。

函数声明提升的具体规则?

分两种场景:

  • 普通函数声明(不在块级语句内):标识符会被提升到作用域顶部,并且直接初始化为对应的函数本体。比如不管function fn() {}写在函数的顶部还是底部,调用时都能直接生效。
  • 块级语句内的函数声明(ES6非严格模式):标识符会被提升到外层函数作用域,但初始值为undefined,只有进入对应的块时,才会把函数赋值给这个标识符。如果块没有被执行,这个变量就会一直保持undefined——这就是你代码里qux的情况。

ES6严格模式下,块内的函数声明会被限制在块级作用域内,此时在块外访问qux就会抛出ReferenceError,但你的代码是非严格模式,所以遵循的是旧规则。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 08:45:32