JavaScript函数调用交换行为分析:不纯函数执行逻辑及输出问题求解
问题解释
核心原因
你遇到的差异本质是因为你定义的f是不纯函数:它依赖外部全局变量multi,且每次调用都会修改这个全局变量的取值,调用顺序会直接影响返回结果。而普通数值加法本身满足交换律,所以已经完成赋值的变量相加不受顺序影响。
逐步骤运行解析
1. 前两次console.log输出均为3的原因
初始状态:multi = 1
- 执行
let a = f(2):
函数内先将multi取反为-1,返回值为2 * (-1) = -2,所以a = -2,此时全局multi = -1 - 执行
let b = f(5):
函数内将multi取反为1,返回值为5 * 1 =5,所以b=5,此时全局multi=1 - 此时
a和b都是固定的普通数值,加法满足交换律,所以a+b = -2+5=3,b+a=5+(-2)=3,两次输出一致。
2. 后两次直接调用函数相加输出结果不同的原因
JS的表达式求值默认是从左到右执行的,调用顺序会改变全局multi的取值,进而影响后续函数返回值:
第三次输出:f(2) + f(5)
此时初始multi = 1(前序赋值完b后的状态)
- 先执行左侧
f(2):multi取反为-1,返回2*(-1) =-2 - 再执行右侧
f(5):multi取反为1,返回5*1=5 - 求和结果:
-2+5=3
第四次输出:f(5) + f(2)
此时初始multi =1(第三次调用完后的状态)
- 先执行左侧
f(5):multi取反为-1,返回5*(-1) =-5 - 再执行右侧
f(2):multi取反为1,返回2*1=2 - 求和结果:
-5+2=-3
相关建议
- 如果要验证函数调用的交换属性,要确保使用纯函数:即函数输出仅依赖输入参数,不修改任何外部状态,也没有其他副作用,此时
f(x)+f(y)和f(y)+f(x)的结果才会一致。 - 如果必须使用依赖外部状态的不纯函数,每次执行测试前要先重置外部状态到初始值,避免前序调用的结果影响后续测试。
内容的提问来源于stack exchange,提问作者Satyam Kumar
相关产品推荐
相关产品推荐

