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

 更新时间:2013年03月04日 11:12:28   作者:  
单个的加号作为运算符在 JavaScript 中有三种作用。

单个的加号作为运算符在 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;

相关文章

  • npm后面的-S和-D参数举例详解

    npm后面的-S和-D参数举例详解

    这篇文章主要给大家介绍了关于npm后面的-S和-D参数举例详解的相关资料,文中还介绍了npm -s和-d的一些区别,对大家的学习或者工作具有一定的参考阶级价值,需要的朋友可以参考下
    2024-01-01
  • JavaScript模块管理的简单实现方式详解

    JavaScript模块管理的简单实现方式详解

    这篇文章主要介绍了JavaScript模块管理的简单实现方式,它方便组织你的代码,提高项目的可维护性。一个项目的可维护性高不高,也体现一个程序员的水平,在如今越来越复杂的前端项目,这一点尤为重要。,需要的朋友可以参考下
    2019-06-06
  • js实现右下角可关闭最小化div(可用于展示推荐内容)

    js实现右下角可关闭最小化div(可用于展示推荐内容)

    使用Javascript实现右下角可关闭最小化div,可以用于展示推荐内容,完整源代码如下,感兴趣的各位可以参下哈,希望对大家有所帮助
    2013-06-06
  • 神级程序员JavaScript300行代码搞定汉字转拼音

    神级程序员JavaScript300行代码搞定汉字转拼音

    这篇文章主要介绍了神级程序员JavaScript300行代码搞定汉字转拼音,需要的朋友可以参考下
    2017-05-05
  • 原生js+ajax分页组件

    原生js+ajax分页组件

    这篇文章主要为大家详细介绍了原生js+ajax分页组件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-01-01
  • js输入框使用正则表达式校验输入内容的实例

    js输入框使用正则表达式校验输入内容的实例

    下面小编就为大家带来一篇js输入框使用正则表达式校验输入内容的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • 一文带你搞懂JavaScript中转义字符的使用

    一文带你搞懂JavaScript中转义字符的使用

    说起转义字符,大家最先想到的肯定是使用反斜杠,这也是我们最常见的,很多编程语言都支持。除了反斜杠以外,在前端开发中,还有其他几种转义字符,也是较常见的,本文将对这些做一个总结
    2023-02-02
  • javascript实现页面滚屏效果

    javascript实现页面滚屏效果

    本文主要介绍了javascript实现页面滚屏效果的方法,具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • 打开新窗口关闭当前页面不弹出关闭提示js代码

    打开新窗口关闭当前页面不弹出关闭提示js代码

    打开新窗口关闭当前页面时总是弹出提示框,有没有办法避免它的弹出呢,答案是可以的接下来为大家分享一个方法可以解决此问题,感兴趣的你可不要错过了哈,希望可以帮助到你
    2013-03-03
  • JavaScript 用cloneNode方法克隆节点的代码

    JavaScript 用cloneNode方法克隆节点的代码

    很多时候我们需要通过HTML DOM 的方式,用JavaScript 动态生成很多相同的节点,包括其子节点
    2012-10-10

最新评论