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 相关文章推荐
javascript比较两个日期的先后示例代码
Dec 31 Javascript
详解JavaScript基于面向对象之创建对象(1)
Dec 10 Javascript
js实现简单排列组合的方法
Jan 27 Javascript
js+css绘制颜色动态变化的圈中圈效果
Jan 27 Javascript
Vue监听数组变化源码解析
Mar 09 Javascript
原生JS实现圆环拖拽效果
Apr 07 Javascript
从源码看angular/material2 中 dialog模块的实现方法
Oct 18 Javascript
利用node实现一个批量重命名文件的函数
Dec 21 Javascript
12条写出高质量JS代码的方法
Jan 07 Javascript
解决layui上传文件提示上传异常,实际文件已经上传成功的问题
Aug 19 Javascript
使用element-ui table expand展开行实现手风琴效果
Mar 15 Javascript
Vue仿百度搜索功能
Dec 28 Vue.js
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
WML,Apache,和 PHP 的介绍
2006/10/09 PHP
PHP 输出简单动态WAP页面
2009/06/09 PHP
php实现的日历程序
2015/06/18 PHP
yii2 modal弹窗之ActiveForm ajax表单异步验证
2016/06/13 PHP
php实现的统计字数函数定义与使用示例
2017/07/26 PHP
javascript高级程序设计第二版第十二章事件要点总结(常用的跨浏览器检测方法)
2012/08/22 Javascript
关于javascript中的typeof和instanceof介绍
2012/12/04 Javascript
javascript中对Attr(dom中属性)的操作示例讲解
2013/12/02 Javascript
jQuery中parentsUntil()方法用法实例
2015/01/07 Javascript
js+css实现超简洁的二级下拉菜单效果代码
2015/09/07 Javascript
走进javascript——不起眼的基础,值和分号
2017/02/24 Javascript
js实现动态显示时间效果
2017/03/06 Javascript
ES6学习教程之模板字符串详解
2017/10/09 Javascript
深入剖析Node.js cluster模块
2018/05/23 Javascript
关于RxJS Subject的学习笔记
2018/12/05 Javascript
JavaScript实现图片的放大缩小及拖拽功能示例
2019/05/14 Javascript
Nodejs中使用puppeteer控制浏览器中视频播放功能
2019/08/26 NodeJs
webpack+vue.js构建前端工程化的详细教程
2020/05/10 Javascript
在Vue中使用Viser说明(基于AntV-G2可视化引擎)
2020/10/28 Javascript
在Python的Django框架中显示对象子集的方法
2015/07/21 Python
简单实现python进度条脚本
2017/12/18 Python
python写入并获取剪切板内容的实例
2018/05/31 Python
python广度优先搜索得到两点间最短路径
2019/01/17 Python
Python lambda表达式filter、map、reduce函数用法解析
2019/09/11 Python
django的模型类管理器——数据库操作的封装详解
2020/04/01 Python
python中for in的用法详解
2020/04/17 Python
Pytorch 卷积中的 Input Shape用法
2020/06/29 Python
浅谈CSS3动画的回调处理
2016/07/21 HTML / CSS
意大利在线大学图书馆:Libreria universitaria
2019/07/16 全球购物
英国网上电器商店:Electricshop
2020/03/15 全球购物
会计专业自荐信
2013/12/02 职场文书
海飞丝的广告词
2014/03/20 职场文书
个人遵守党的政治纪律情况对照检查材料思想汇报
2014/09/25 职场文书
2015年秋学期教研工作总结
2015/10/14 职场文书
CSS实现隐藏搜索框功能(动画正反向序列)
2021/07/21 HTML / CSS
css3中transform属性实现的4种功能
2021/08/07 HTML / CSS