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 相关文章推荐
一个收集图片的bookmarlet(js 刷新页面中的图片)
May 27 Javascript
关于用Jquery的height()、width()计算动态插入的IMG标签的宽高的问题
Dec 08 Javascript
JS对外部文件的加载及对IFRMAME的加载的实现,当加载完成后,指定指向方法(方法回调)
Jul 04 Javascript
处理及遍历XML文档DOM元素属性及方法整理
Aug 23 Javascript
转换字符串为json对象的方法详解
Nov 29 Javascript
在myeclipse中如何加入jquery代码提示功能
Jun 03 Javascript
JS取得绝对路径的实现代码
Jan 16 Javascript
js实现的全国省市二级联动下拉选择菜单完整实例
Aug 17 Javascript
jQuery手指滑动轮播效果
Dec 22 Javascript
JS实现数组简单去重及数组根据对象中的元素去重操作示例
Jan 05 Javascript
JS使用cookie保存用户登录信息操作示例
May 30 Javascript
Node.js控制台彩色输出的方法与原理实例详解
Dec 01 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
PHP Warning: PHP Startup: Unable to load dynamic library \ D:/php5/ext/php_mysqli.dll\
2012/06/17 PHP
使用php检测用户当前使用的浏览器是否为IE浏览器
2013/12/03 PHP
PHP解析html类库simple_html_dom的转码bug
2014/05/22 PHP
php的ZipArchive类用法实例
2014/10/20 PHP
ThinkPHP在新浪SAE平台的部署实例
2014/10/31 PHP
php计算整个mysql数据库大小的方法
2015/06/19 PHP
如何判断php mysqli扩展类是否开启
2016/12/24 PHP
PHP实现上传多文件示例代码
2017/02/20 PHP
几个javascript操作word的参考代码
2009/10/26 Javascript
找出字符串中出现次数最多的字母和出现次数精简版
2012/11/07 Javascript
js 一个关于图片onload加载的事
2013/11/10 Javascript
基于NodeJS的前后端分离的思考与实践(三)轻量级的接口配置建模框架
2014/09/26 NodeJs
jquery-tips悬浮提示插件分享
2015/07/31 Javascript
javascript实现二叉树遍历的代码
2017/06/08 Javascript
详解React Native 采用Fetch方式发送跨域POST请求
2017/11/15 Javascript
利用js给datalist或select动态添加option选项的方法
2018/01/25 Javascript
纯js封装的ajax功能函数与用法示例
2018/05/14 Javascript
JS实现获取毫秒值及转换成年月日时分秒的方法
2018/08/15 Javascript
Vue中的vue-resource示例详解
2018/11/02 Javascript
vuex如何重置所有state(可定制)
2019/01/17 Javascript
tweenjs缓动算法的使用实例分析
2019/08/26 Javascript
Python网页解析利器BeautifulSoup安装使用介绍
2015/03/17 Python
通过数据库对Django进行删除字段和删除模型的操作
2015/07/21 Python
Python+django实现文件下载
2016/01/17 Python
详解Python使用simplejson模块解析JSON的方法
2016/03/24 Python
PyQt5中QTableWidget如何弹出菜单的示例代码
2020/02/23 Python
Python Tkinter Entry和Text的添加与使用详解
2020/03/04 Python
详解前端HTML5几种存储方式的总结
2016/12/27 HTML / CSS
新秀丽拉杆箱美国官方网站:Samsonite美国
2016/07/25 全球购物
简单而又朴实的个人求职信分享
2013/12/12 职场文书
奥巴马演讲稿
2014/01/08 职场文书
学员自我鉴定
2014/03/19 职场文书
自我推荐信范文
2014/05/09 职场文书
中小学校园安全广播稿
2014/09/29 职场文书
考试没考好检讨书(精选篇)
2014/11/16 职场文书
出国留学自荐信模板
2015/03/06 职场文书