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 插件实现图片延迟加载效果代码
Feb 06 Javascript
HTML,CSS,JavaScript速查表推荐
Dec 02 Javascript
jQuery中add()方法用法实例
Jan 08 Javascript
自己编写的支持Ajax验证的JS表单验证插件
May 15 Javascript
浅谈JavaScript中的string拥有方法的原因
Aug 28 Javascript
JS和jQuery使用submit方法无法提交表单的原因分析及解决办法
May 17 Javascript
PHP获取当前页面完整URL的方法
Dec 02 Javascript
jQuery实现的浮动层div浏览器居中显示效果
Feb 03 Javascript
VUEJS 2.0 子组件访问/调用父组件的实例
Feb 10 Javascript
Vue中&quot;This dependency was not found&quot;问题的解决方法
Jun 19 Javascript
vue 实现移动端键盘搜索事件监听
Nov 06 Javascript
Vue实现简单的跑马灯
May 25 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 Ajax中文乱码问题解决方法
2009/02/27 PHP
浅析PHP中的UNICODE 编码与解码
2013/06/29 PHP
Centos6.5和Centos7 php环境搭建方法
2016/05/27 PHP
php 字符串中是否包含指定字符串的多种方法
2018/04/12 PHP
PHP7 新增功能
2021/03/09 PHP
扩展jQuery 键盘事件的几个基本方法
2009/10/30 Javascript
表单切换,用回车键替换Tab健(不支持IE)
2011/07/20 Javascript
jQuery最佳实践完整篇
2011/08/20 Javascript
js 在定义的时候立即执行的函数表达式(function)写法
2013/01/16 Javascript
Firefox和IE兼容性问题及解决方法总结
2013/10/08 Javascript
简单谈谈javascript中的变量、作用域和内存问题
2015/08/30 Javascript
JS利用cookie记忆当前位置的防刷新导航效果
2015/10/15 Javascript
JS中innerHTML和pasteHTML的区别实例分析
2016/06/22 Javascript
JavaScript 对象详细整理总结
2016/09/29 Javascript
浅谈Node.js ORM框架Sequlize之表间关系
2017/07/24 Javascript
Angular4.0中引入laydate.js日期插件的方法教程
2017/12/25 Javascript
JS高阶函数原理与用法实例分析
2019/01/15 Javascript
微信小程序顶部导航栏滑动tab效果
2019/01/28 Javascript
微信小程序之高德地图多点路线规划过程示例详解
2021/01/18 Javascript
[02:32]DOTA2英雄基础教程 美杜莎
2014/01/07 DOTA
Python中还原JavaScript的escape函数编码后字符串的方法
2014/08/22 Python
不归路系列:Python入门之旅-一定要注意缩进!!!(推荐)
2019/04/16 Python
Python两台电脑实现TCP通信的方法示例
2019/05/06 Python
python爬虫之自制英汉字典
2019/06/24 Python
使用PYTHON解析Wireshark的PCAP文件方法
2019/07/23 Python
python栈的基本定义与使用方法示例【初始化、赋值、入栈、出栈等】
2019/10/24 Python
python 代码运行时间获取方式详解
2020/09/18 Python
浅析Python中字符串的intern机制
2020/10/03 Python
实例教程 纯CSS3打造非常炫的加载动画效果
2014/11/05 HTML / CSS
耐克中国官方商城:Nike中国
2018/10/18 全球购物
GC是什么?为什么要有GC?
2013/12/08 面试题
公司开业庆典策划方案
2014/06/04 职场文书
2016春季运动会通讯稿
2015/07/18 职场文书
纯CSS3实现div按照顺序出入效果
2021/07/15 HTML / CSS
MySQL约束超详解
2021/09/04 MySQL
Python几种酷炫的进度条的方式
2022/04/11 Python