JavaScript箭头函数作为默认参数的输出结果差异疑问
结果逻辑详解
这个输出的核心是 ES6 带默认值的函数参数的独立作用域规则 + 同名var声明的特殊处理,我们按执行顺序拆解就能完全理清:
执行步骤拆解
步骤1:参数作用域初始化
调用函数传入实参1时,因为第二个参数f配置了默认值,JS会先创建一个和函数体隔离的独立参数作用域,按顺序初始化参数:
- 形参
x被赋值为传入的1,参数作用域内的x固定初始值为1 - 形参
f被赋值为箭头函数() => x,箭头函数的词法作用域绑定的是当前的参数作用域,它内部引用的x永远指向参数作用域的x,不受函数体内部操作的影响。
步骤2:函数体变量提升
参数初始化完成后进入函数体,首先处理变量提升:
- 函数体内的
var x和形参同名,JS不会重复创建变量,也不会修改现有x的值,相当于这条声明被跳过,此时函数体访问到的x还是参数作用域传入的1 var y被提升,初始值为undefined
步骤3:逐行执行函数体代码
var x;:已经在变量提升阶段处理完成,没有任何实际执行效果var y = x;:此时x的值还是1,所以y被赋值为1x = 2;:因为前面声明了同名的var x,这个赋值只会修改函数体作用域下的x值,不会改动参数作用域里的x,参数作用域的x还是保持初始的1- 返回结果:
- 第一个值是函数体作用域的
x,已经被修改为2 - 第二个值是
y,之前赋值的1 - 第三个值是
f()的执行结果,指向参数作用域的x,还是1
所以最终输出为2,1,1。
- 第一个值是函数体作用域的
补充验证
你可以尝试把函数体内的var x;删掉,运行结果会变成2,1,2,此时没有同名var声明,x=2会直接修改参数作用域的x,所以f()会返回修改后的值2,可以反向验证上面的逻辑。
内容的提问来源于stack exchange,提问作者Deepak _8097
相关产品推荐
相关产品推荐

