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

JavaScript函数参数默认值为何表现不同?解析两种场景差异

为什么两段带参数默认值的JS代码执行结果不同?

这问题的核心其实是ES6函数参数默认值的一个特性:参数会创建一个独立的作用域,咱们一步步拆解两段代码的执行逻辑就清楚了。

先看代码1的执行过程

代码如下:

function foo(x = 2, y = function() { return x; }) {
  var x = 5;
  console.log(y()) // 输出2
}
foo();
  1. 调用foo()时,JS会先处理参数部分,这里会生成一个参数专属的作用域:
    • 参数x被赋予默认值2,此时这个作用域里有个x变量,值是2。
    • 参数y的默认函数是在这个参数作用域里定义的,所以它会“记住”这个作用域,里面的x指向的就是参数作用域里的那个x。
  2. 进入函数体后,var x = 5其实做了两件事:
    • 变量提升:在函数体作用域的顶部提前声明了一个新的x变量(和参数作用域的x完全是两个东西)。
    • 给这个新的x赋值为5。
  3. 当执行y()时,函数y会去自己绑定的参数作用域找x,拿到的是最初的默认值2,所以控制台输出2。

再看代码2的执行过程

代码如下:

function foo(x = 2, y = function() { return x; }) {
  x = 5;
  console.log(y()) // 输出5
}
foo();
  1. 同样,调用foo()时先进入参数作用域:
    • 参数x默认值为2,y的函数依然绑定参数作用域的x。
  2. 进入函数体后,x = 5没有用var/let/const声明变量,所以JS会沿着作用域链往上找:
    • 首先找到的就是参数作用域里的那个x,直接把它的值改成5。
  3. 执行y()时,函数y从参数作用域拿到的是修改后的x值5,所以控制台输出5。

简单总结一下:

  • 代码1里的var x = 5是在函数体作用域重新声明了一个同名变量,和参数作用域的x互不干扰;
  • 代码2里的x = 5是直接修改了参数作用域里的x,所以被y函数捕获到了变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:00:57