JavaScript 运算数求值顺序:副作用与跨语言差异解析

作者:纸飞机时间:2026-10-26 12:50:26浏览:262

本文深入探讨JavaScript中运算数的求值顺序,特别是当运算数包含具有副作用的函数时的行为差异。通过对比JavaScript与C语言在相同代码逻辑下的不同结果,揭示了从左到右求值与先执行函数再取值的具体机制,帮助开发者避免因求值顺序导致的潜在Bug。

JavaScript 运算数求值顺序:副作用与跨语言差异解析

例如


代码如下:

 
a * b + c;

数学运算遵循先乘方、再乘除、最后加减的规则


若存在括号,优先计算括号内的内容;同一优先级运算则按从左到右顺序依次进行


所有程序设计语言均沿用数学中的数字计算顺序,尽管编程语言引入了部分特殊运算符。那么,运算数的具体求值顺序究竟如何?


如下


代码如下:

 
// 求 a 和 b的和
sum = a + b;

系统从内存中获取a的值


系统从内存中获取b的值


执行相加运算


上述描述看似基础且理所当然。有人或许认为先取b的值、再取a的值,最后相加,结果也是一样的。确实如此,但如果运算数是一个函数执行呢?


sum = a + fun();


假设fun函数仅返回一个数字。此时,无论先取a的值还是先执行fun(),最终结果均相同。这似乎并无新意,也未触及核心纠结点。


但如果fun函数不仅返回数字,还改变了变量a的值呢?例如以下JavaScript代码


代码如下:

 
var a = 5;
function fun(){
a = 10;
return 20;
} 
var b = a + fun(); // b 的值?

fun函数不仅返回了20,还改变了a的值。而a正是参与相加运算的变量。此时,a取5还是10参与相加运算呢?若取5,则b的值为25;若取10,则b为30。在JavaScript语言中,结果是25。但在C语言中,结果却是30,如下


代码如下:

 
int a = 5;
int fun(){
a = 10;
return 20;
} 
int b = a + fun(); // 30

因此,只有当函数存在副作用时,运算数的求值顺序不同才会导致结果不同。显然,各语言实现存在差异。


在JavaScript语言中,遵循从左到右的顺序:先取a的值5,再执行fun()返回20,最终计算5+20。需注意,虽然参与此次运算时a取值为5,但a的实际值在fun执行后已改变。如下


代码如下:

 
var a = 5;
function fun(){
a = 10;
return 20;
} 
var b = a + fun(); // b 的值?
alert(a); // 10

在C语言中,先执行fun函数,fun内部将a的值改为10,随后取a的值10参与本次加法运算,fun返回20。最终结果为10+20。


可以看到,无论是JavaScript还是C语言,a的最终值都变为10。区别在于:参与相加运算时,JavaScript取未被改变前的值5,而C语言取已被改变后的值10。


C语言中,运算同样是从左到右进行的。但当运算数包含函数时,会先执行该函数。若该函数有副作用,则取被改变后的a值参与本次运算。无论fun和a的顺序如何,如下将fun放在前面,在C语言中结果仍然是30


代码如下:

 
int a = 5;
int fun(){
a = 10;
return 20;
} 
int b = fun() + a; // 30

在JavaScript中,如果fun与a交换了顺序,则结果不再是25。


代码如下:

 
var a = 5;
function fun(){
a = 10;
return 20;
} 
var b = fun() + a; // b为30

相关:


函数的副作用

作者最新文章