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 初体验(建议学习jquery)
Apr 25 Javascript
js操作checkbox遇到的问题解决
Jun 29 Javascript
Javascript中匿名函数的多种调用方式总结
Dec 06 Javascript
JQuery的$命名冲突详细解析
Dec 28 Javascript
JQuery+Ajax无刷新分页的实例代码
Feb 08 Javascript
网页中JS函数自动执行常用三种方法
Mar 30 Javascript
Vue 2.0的数据依赖实现原理代码简析
Jul 10 Javascript
vue自定义tap指令及tap事件的实现
Sep 18 Javascript
Vue 处理表单input单行文本框的实例代码
May 09 Javascript
JS常用正则表达式超全集(密码强度校验,金额校验,IE版本,IPv4,IPv6校验)
Feb 03 Javascript
Vue2.x和Vue3.x的双向绑定原理详解
Nov 05 Javascript
vue实现验证用户名是否可用
Jan 20 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
再次研究下cache_lite
2007/02/14 PHP
php empty,isset,is_null判断比较(差异与异同)
2010/10/19 PHP
PHP+MySQL投票系统的设计和实现分享
2012/09/23 PHP
php cli 小技巧
2013/06/03 PHP
php中hashtable实现示例分享
2014/02/13 PHP
详解WordPress开发中用于获取分类及子页面的函数用法
2016/01/08 PHP
php5.5使用PHPMailer-5.2发送邮件的完整步骤
2018/10/14 PHP
JavaScript While 循环基础教程
2007/04/05 Javascript
javascript attachEvent和addEventListener使用方法
2009/03/19 Javascript
基于jquery的鼠标拖动效果代码
2012/05/30 Javascript
js为鼠标添加右击事件防止默认的右击菜单弹出
2013/07/29 Javascript
JS 去除Array中的null值示例代码
2013/11/20 Javascript
Ajax提交与传统表单提交的区别说明
2014/02/07 Javascript
多个checkbox被选中时如何判断是否有自己想要的
2014/09/22 Javascript
jQuery支持动态参数将函数绑定到事件上的方法
2015/03/17 Javascript
js+canvas绘制矩形的方法
2016/01/28 Javascript
微信小程序 http请求详细介绍
2016/10/09 Javascript
TypeScript入门-接口
2017/03/30 Javascript
解决jQuery ajax动态新增节点无法触发点击事件的问题
2017/05/24 jQuery
JavaScript之浏览器对象_动力节点Java学院整理
2017/07/03 Javascript
nodejs实现简单的gulp打包
2017/12/21 NodeJs
layui数据表格重载实现往后台传参
2019/11/15 Javascript
微信小程序实现转盘抽奖
2020/09/21 Javascript
OpenLayers3实现对地图的基本操作
2020/09/28 Javascript
Python在Console下显示文本进度条的方法
2016/02/14 Python
Python发送邮件测试报告操作实例详解
2018/12/08 Python
python3使用matplotlib绘制散点图
2019/03/19 Python
Python socket实现的文件下载器功能示例
2019/11/15 Python
pycharm的python_stubs问题
2020/04/08 Python
tensorflow常用函数API介绍
2020/04/19 Python
torchxrayvision包安装过程(附pytorch1.6cpu版安装)
2020/08/26 Python
css3圆角边框和边框阴影示例
2014/05/05 HTML / CSS
KIEHL’S科颜氏官方旗舰店:源自美国的顶级护肤品牌
2018/06/07 全球购物
承诺书格式
2014/06/03 职场文书
社区矫正工作方案
2014/06/04 职场文书
教师个人考察材料
2014/12/16 职场文书