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

为什么非严格模式下该JS代码最后输出3 a: 1而非3 a: 5?

核心原因:非严格模式下块内函数声明的特殊提升规则

这个现象是ES规范为了兼容旧代码留下的历史遗留行为,仅在非严格模式下生效。严格模式中块内函数声明只会提升到块顶部,不会对外层作用域产生影响。

逐阶段执行逻辑拆解

先明确非严格模式下块级函数的两个特殊规则:

  • 块内的function a()声明会做两次提升:一次提升到外层作用域(本次是全局作用域),初始值为undefined;第二次提升到当前块的顶部,初始值为函数本身
  • 当代码执行到function a()原本所在的行位置时,会自动把当前块内a的最新值同步覆盖到外层作用域的a上

整个代码的执行流程如下:

  1. 全局预编译阶段
    扫描到全局var a和块内function a()两个声明,非严格模式下块内函数仅给全局a绑定标识,初始值为undefined,因此第一行console.log('1 a: ' + a)输出undefined。

  2. 进入if块执行

    • 块预编译阶段,function a()提升到块顶,块作用域内的a初始值为函数对象
    • 执行a = 1:修改的是块作用域内的a,此时块内a=1,全局a还是undefined
    • 执行到function a() { }所在行:触发同步逻辑,把块内a的当前值1同步到全局a,此时全局a=1
    • 执行a = 5:修改的仍然是块作用域内的a,块内a=5,全局a保持1不变
    • 执行块内打印,读取块内的a,输出2 a: 5
  3. 退出if块执行最后一行打印
    块作用域销毁,此时访问的是全局作用域的a,值为之前同步的1,因此输出3 a: 1,而非块内最后赋值的5。

验证规则的小测试

你可以调整代码验证逻辑:

  • 把function a() { }移到a = 5之后,最后全局打印结果就会变成5,因为触发同步时块内a已经是5了
  • 开头加'use strict'开启严格模式,最后全局打印结果也会是5,因为严格模式下块内函数不会同步到外层作用域

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:36:04