javascript加号"+"的二义性说明


Posted in Javascript onMarch 04, 2013

单个的加号作为运算符在 JavaScript 中有三种作用。它可以表示字符串连接,例如:

var str = 'hello ' + 'world!';

或表示数字取正值的一元运算符,例如:

var n = 10;  
var n2 = +n;

或表示数值表达式的求和运算,例如:

var n = 100;  
var nn2 = n + 1; 
 

三种表示法里,字符串连接与数字求和是容易出现二义性的。因为 JavaScript 中对这两种运算的处理将依赖于数据类型,而无法从运算符上进行判读。我们单独地看一个表达式:

aa = a + b;

是根本无法知道它真实的含义是在求和,亦或是在做字符串连接。这在 JavaScript 引擎做语法分析时,也是无法确知的。

加号"+"带来的主要问题与另一条规则有关。这条规则是"如果表达式中存在字符串,则优先按字符串连接进行运算"。例如:

var v1 = '123';  
var v2 = 456;  //显示结果值为字符串'123456'  
alert( v1 + v2 );

这会在一些宿主中出现问题。例如浏览器中,由于 DOM 模型的许多值看起来是数字,但实际上却是字符串。因此试图做"和"运算,却变成了"字符串连接"运算。下面的例子说明了这个问题:

<img id="testPic" style="border: 1 solid red"> 
 

我们看到这个 id 为 testPic 的 IMG 元素(element)有一个宽度为 1 的边框--省略了默认的单位 px(pixel,像素点)。但是如果你试图用下面的代码来加宽它的边框,就会导致错误(一些浏览器忽略该值,另一些则弹出异常,还有一些浏览器则可能崩溃):

var el = document.getElementById('testPic');  
el.style.borderWidth += 10; 
 

因为事实上在 DOM 模型里,borderWidth 是有单位的字符串值,因此这里的值会是"1px"。JavaScript 本身并不会出错,它会完成类似下面的运算,并将值赋给 borderWidth:

el.style.borderWidth = '1px' + 10;  
//值为 '1px10'

这时,浏览器的 DOM 模型无法解释"1px10"的含义,因此出错了。当你再次读borderWidth 值时,它将仍是值 1px。那么,怎么证明上述的运算过程呢?下面的代码将表明 JavaScript 运算的结果是 1px10,但赋值到 borderWidth 时,是由于 DOM 忽略掉这个错误的值,因此 borderWidth 没有发生实际的修改:

alert( el.style.borderWidth = '1px' + 10 );//值为 '1px10'

这个问题追其根源,一方面在于我们允许了省略单位的样式表写法,另一方面也在于脚本引擎不能根据运算符来确定这里的操作是数值运算还是字符串连接。

后来 W3C 推动 XHTML 规范,试图从第一个方面来避免这个问题,但对开发界的影响仍旧有限。因此,在浏览器的开发商提供的手册中,都会尽可能地写明每一个属性的数据类型,以避免开发人员写出上面这样的代码。在这种情况下,最正确的写法是:

var el = document.getElementById('testPic');  
// 1.取原有的单位  
var value = parseInt(el.style.borderWidth);  
var unit = el.style.borderWidth.substr(value.toString().length);  
// 2.运算结果并附加单位  
el.style.borderWidth = value + 10 + unit;  //如果你确知属性采用了默认单位 px,并试图仍然省略单位值,  
//那么你可以用下面这种方法(我并不推荐这样):  
// el.style.borderWidth = parseInt(el.style.borderWidth) + 10;
Javascript 相关文章推荐
jQuery 在光标定位的地方插入文字的插件
May 10 Javascript
jQuery.Validate验证库的使用介绍
Apr 26 Javascript
javascript 面向对象封装与继承
Nov 27 Javascript
9款2014最热门jQuery实用特效推荐
Dec 07 Javascript
异步JavaScript编程中的Promise使用方法
Jul 28 Javascript
avalon js实现仿微博拖动图片排序
Aug 14 Javascript
JS 实现Base64编码与解码实例详解
Nov 07 Javascript
微信小程序 删除项目工程实现步骤
Nov 10 Javascript
node操作mysql数据库实例详解
Mar 17 Javascript
VsCode新建VueJs项目的详细步骤
Sep 23 Javascript
vue实现数字滚动效果
Jun 29 Javascript
vue 二维码长按保存和复制内容操作
Sep 22 Javascript
js给dropdownlist添加选项的小例子
Mar 04 #Javascript
jQuery侧边栏随窗口滚动实现方法
Mar 04 #Javascript
利用js实现选项卡的特别效果的实例
Mar 03 #Javascript
DWZ刷新dialog解决方法
Mar 03 #Javascript
js 控制下拉菜单刷新的方法
Mar 03 #Javascript
可在线编辑网页文字效果代码(单击)
Mar 02 #Javascript
javascript重复绑定事件造成的后果说明
Mar 02 #Javascript
You might like
discuz 首页四格:最新话题+最新回复+热门话题+精华文章插件
2007/08/19 PHP
mysql limit查询优化分析
2008/11/12 PHP
php mssql 分页SQL语句优化 持续影响
2009/04/26 PHP
iis下php mail函数的sendmail配置方法(官方推荐)
2012/04/25 PHP
用javascript实现的图片马赛克后显示并切换加文字功能
2007/04/21 Javascript
对象特征检测法判断浏览器对javascript对象的支持
2009/07/25 Javascript
Jquery实现控件的隐藏和显示实例
2014/02/08 Javascript
JS实现CheckBox复选框全选全不选功能
2015/05/06 Javascript
JS脚本根据手机浏览器类型跳转WAP手机网站(两种方式)
2015/08/04 Javascript
使用jquery提交form表单并自定义action的方法
2016/05/25 Javascript
AngularJS 整理一些优化的小技巧
2016/08/18 Javascript
浅谈struts1 &amp; jquery form 文件异步上传
2017/05/25 jQuery
vue中实现图片和文件上传的示例代码
2018/03/16 Javascript
VueJs组件之父子通讯的方式
2018/05/06 Javascript
layui监听select变化,以及设置radio选中的方法
2019/09/24 Javascript
vue实现Input输入框模糊查询方法
2021/01/29 Javascript
纯 JS 实现放大缩小拖拽功能(完整代码)
2019/11/25 Javascript
JavaScript使用canvas绘制随机验证码
2020/02/17 Javascript
Python、Javascript中的闭包比较
2015/02/04 Python
python里使用正则的findall函数的实例详解
2017/10/19 Python
详解Python异常处理中的Finally else的功能
2017/12/29 Python
Python使用paramiko操作linux的方法讲解
2019/02/25 Python
完美解决keras 读取多个hdf5文件进行训练的问题
2020/07/01 Python
CSS3制作缩略图的详细过程
2016/07/08 HTML / CSS
HTML5制作表格样式
2016/11/15 HTML / CSS
Vertbaudet西班牙网上商店:婴儿服装、童装、母婴用品和儿童家具
2019/10/16 全球购物
初中生三年学习生活的自我评价
2013/11/03 职场文书
生物制药专业求职信
2014/03/11 职场文书
教师演讲稿大全
2014/05/16 职场文书
2015公务员试用期工作总结
2014/12/12 职场文书
大学运动会通讯稿
2015/07/18 职场文书
同事离别感言
2015/08/04 职场文书
运动会200米广播稿
2015/08/19 职场文书
Java并发编程必备之Future机制
2021/06/30 Java/Android
如何开启Apache,Nginx和IIS服务器的GZIP压缩功能
2022/04/29 Servers
Python实战实现爬取天气数据并完成可视化分析详解
2022/06/16 Python