javascript 运算数的求值顺序


Posted in Javascript onAugust 23, 2011

比如

a * b + c;

,先算乘方,再算乘除,最后算加减
,有括号,先算括号里面的,同一级运算按照从左到右的顺序依次进行
这一点所有的程序设计语言都采取数学中数字的计算顺序。当然程序设计语言中还有一些不同于数学中的运算符。那运算数的求值顺序是如何的呢?
如下
// 求 a 和 b的和 
sum = a + b;

,从内存中取a的值
,从内存中取b的值
,进行相加运算
貌似描述的很弱智,理所当然就是这样的。有人可能觉得先取b的值,再取a,然后相加。这样最后的结果也是一样的。的确是这样。但如果运算数是一个函数执行呢?
sum = a + fun();
假设fun函数中仅return 一个数字。这时无论是先取a的值,再去fun执行后的值也是无所谓的。最终的结果都一样。说到这里,仍然没有新鲜,纠结的地方。
但如果fun不仅返回了数字,还改变了a呢? 比如以下JavaScript代码
var a = 5; 
function fun(){ 
a = 10; 
return 20; 
} 
var b = a + fun(); // b 的值?

fun 函数不仅返回了20,还改变了a的值。而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值实际上已经改变了。如下
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

相关:
函数的副作用
Javascript 相关文章推荐
javascript 面向对象继承
Nov 26 Javascript
jquery可定制的在线UEditor编辑器
Nov 17 Javascript
浅析jQuery事件之on()方法绑定多个选择器,多个事件
Apr 27 Javascript
jQuery实现手机自定义弹出输入框
Jun 13 Javascript
JCrop+ajaxUpload 图像切割上传的实例代码
Jul 20 Javascript
Angular懒加载机制刷新后无法回退的快速解决方法
Aug 30 Javascript
BootStrap入门教程(二)之固定的内置样式
Sep 19 Javascript
js事件冒泡与事件捕获详解
Feb 20 Javascript
vue+vuex+axio从后台获取数据存入vuex实现组件之间共享数据
Apr 22 Javascript
Webpack devServer中的 proxy 实现跨域的解决
Jun 15 Javascript
Vue循环组件加validate多表单验证的实例
Sep 18 Javascript
解决antd的Form组件setFieldsValue的警告问题
Oct 29 Javascript
读jQuery之十四 (触发事件核心方法)
Aug 23 #Javascript
读jQuery之十三 添加事件和删除事件的核心方法
Aug 23 #Javascript
基于jquery实现的类似百度搜索的输入框自动完成功能
Aug 23 #Javascript
jquery 回车事件实现代码
Aug 23 #Javascript
基于jquery的大众点评,分类导航实现代码
Aug 23 #Javascript
20个非常棒的 jQuery 幻灯片插件和教程分享
Aug 23 #Javascript
基于jquery实现的鼠标拖拽元素复制并写入效果
Aug 23 #Javascript
You might like
ubuntu 编译安装php 5.3.3+memcache的方法
2010/08/05 PHP
php中的boolean(布尔)类型详解
2013/10/28 PHP
PHP中的Streams详细介绍
2014/11/12 PHP
PHP实现获取并生成数据库字典的方法
2016/05/04 PHP
php编程实现简单的网页版计算器功能示例
2017/04/26 PHP
PHP实现将标点符号正则替换为空格的方法
2017/08/09 PHP
php微信支付之公众号支付功能
2018/05/30 PHP
PHP cookie与session会话基本用法实例分析
2019/11/18 PHP
htm调用JS代码
2007/03/15 Javascript
JS运行耗时操作的延时显示方法
2010/11/19 Javascript
在vs2010中调试javascript代码方法
2011/02/11 Javascript
jquery实现点击TreeView文本父节点展开/折叠子节点
2013/01/10 Javascript
jQuery实现横向带缓冲的水平运动效果(附demo源码下载)
2016/01/29 Javascript
JavaScript实现页面跳转的方式汇总
2016/05/16 Javascript
HTML5 实现的一个俄罗斯方块实例代码
2016/09/19 Javascript
JS命令模式例子之菜单程序
2016/10/10 Javascript
SelecT下拉框选中和取值的解决方法
2016/11/22 Javascript
详解js树形控件—zTree使用总结
2016/12/28 Javascript
jQuery实现遮罩层登录对话框
2016/12/29 Javascript
bootstrap3中container与container_fluid外层容器的区别讲解
2017/12/04 Javascript
Vue 实现拖动滑块验证功能(只有css+js没有后台验证步骤)
2018/08/24 Javascript
解决vue中监听input只能输入数字及英文或者其他情况的问题
2018/08/30 Javascript
React优化子组件render的使用
2019/05/12 Javascript
Electron 打包问题:electron-builder 下载各种依赖出错(推荐)
2020/07/09 Javascript
解决vue cli4升级sass-loader(v8)后报错问题
2020/07/30 Javascript
对Python协程之异步同步的区别详解
2019/02/19 Python
python 有效的括号的实现代码示例
2019/11/11 Python
python GUI库图形界面开发之PyQt5动态(可拖动控件大小)布局控件QSplitter详细使用方法与实例
2020/03/06 Python
如何导出python安装的所有模块名称和版本号到文件中
2020/06/05 Python
Python Tornado核心及相关原理详解
2020/06/24 Python
说出你对remoting 和webservice的理解和应用
2014/06/08 面试题
计算机科学技术自荐信
2014/06/12 职场文书
教师个人教学总结
2015/02/11 职场文书
2015年派出所工作总结
2015/04/24 职场文书
浪漫的婚礼主持词
2015/06/30 职场文书
css常用字体属性与背景属性介绍
2022/02/28 HTML / CSS