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;

(0)

相关推荐

  • 完美解决js传递参数中加号和&号自动改变的方法

    在action中用get方法获得参数,如果参数里有"+",要做处理,否则到后台会变成空格. 解决方案: 1 .改用post方法: 2 .在 js 里用 url = encodeURI(encodeURI(XXX)) ,后台再解码一次: 3 .传递参数的时候直接替换转义,或者直接写转义后的代码 data =  "a + b": data = data.replace(/\+/g, "+"); data = data.replace(/\&/

  • JavaScript调用传递变量参数的相关问题及解决办法

    举例 有一个js方法,接收参数: 复制代码 代码如下: function f1(myValue){ alert(myValue); } 有一个变量: 复制代码 代码如下: var passValue="Hello World"; 在调用这个方法的时候(我是出现在Ajax提交的时候): @Ajax.ActionLink("文本","控制器",new{参数},new AjaxOptions(){ HttpMethod="post"

  • javascript中加号(+)操作符的一些神奇作用

    javascript是一门神奇的语言,这没神奇的语言中有一个神奇的加操作符. 常用的加操作符我们可以用来做: 1.加法运算,例如:alert(1+2); ==>32.字符串连接,例如:alert("a"+"b");==>"ab" 高级一点的还有"+=",也是做以上两种操作的. 昨天在javascript丛林群里问了问题:怎么把"2000-09-11 19:22"这个日期格式字符串转换成毫秒数?

  • 浅谈在js传递参数中含加号(+)的处理方式

    一般情况下,URL 中的参数应使用 url 编码规则,即把参数字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+). 但是对于带有中文的参数来说,这种编码会使编码后的字符串变得很长. 如果希望有短一点的方式对参数编码,可以采用 base64 编码方式对字符串进行编码,但是 base64 编码方式不能处理 JavaScript 中的中文,因为 JavaScript 中的中文都是以 UTF-16 方式保存的. 而 base64 只能处理单字

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

    单个的加号作为运算符在 JavaScript 中有三种作用.它可以表示字符串连接,例如: 复制代码 代码如下: var str = 'hello ' + 'world!'; 或表示数字取正值的一元运算符,例如: 复制代码 代码如下: var n = 10;  var n2 = +n; 或表示数值表达式的求和运算,例如: 复制代码 代码如下: var n = 100;  var nn2 = n + 1; 三种表示法里,字符串连接与数字求和是容易出现二义性的.因为 JavaScript 中对这两种运

  • JavaScript 加号(+)运算符号

    一,对于引用类型对象(我指的是String,Date,Object,Array,Function,Boolean)的+运算符运算过程如下! 1,首先调用此对象的valueOf方法,得到返回数值A 2,然后把此数值A转换成数字,得到的是最终数值 我的测试如下: 复制代码 代码如下: function w(s){ document.writeln("<br/>"); document.writeln(s); document.writeln("<br/>-

  • javascript的 {} 语句块详解

    今日学习解析json字符串,用到了一个eval()方法,解析字符串的时候为什么需要加上括号呢?摸不着头脑.原来javascript中{}语句块具有二义性,不加括号会出错,理解这种二义性对我们理解javascript代码有极大帮助. 一.{}语句块的两个含义 表示语句块 a. 在javascript中可以使用{}来括起代码,在编辑器中方便管理代码.因为javascript并没有块级作用域,所以这种写法是无害的. { //some code... } b. 在javascript中 ,条件判断语句,

  • 深入浅析JavaScript函数前面的加号和叹号

    +function(){}(); 这里的加号,也可以替换成!,~等其他一元操作符,其效果相当于: (function() { console.log("Foo!"); })(); // or (function() { console.log("Foo!"); }()); 如果没有这个加号的话,解析器会认为function是一个函数声明的开始,而后面()将会导致语法错误.在function前面加上+号时,就变成了一个函数表达式,而函数表达式后面又添加了一个()就变成

  • 如何使用JavaScript和正则表达式进行数据验证

    数据验证是网络应用软件从客户端接受数据的重要步骤,毕竟,您需要在使用客户数据前确保其符合预期的格式.在网络应用程序中,您可以选择使用特定平台的工具,比如ASP.NET.JSP等等,或者您可以利用客户端JavaScript的优势,JavaScript中的正则表达式可以简化数据验证的工作. 正则表达式 正则表达式是一种模式匹配的工具,它允许您以文字方式来表述模式,因而正则表达式成为了一个验证文本数据的强大工具.除了模式匹配之外,正则表达式还可以用于文字替换.从我在UNIX系统上使用Perl时第一次接

  • JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型

    ECMAScript是一种动态类型的语言,构建于5种简单数据类型(Undefined.Null.Boolean.Number.String)和一种复杂数据类型(Object)的基础之上.这篇文章就来复习一下简单数据类型,我会尽量从编程实践的角度来描述,下面代码运行环境为FireFox 14.0.1. 简单数据类型 简单数据类型 取值 Undefined undefined(只有一个值) Null null(只有一个值) Boolean true|false(只有两个值) Number 数值 St

  • Javascript的比较汇总

    在Javascript应用过程中会遇到各式各样的比较,今天给大家整理了三种情况,一起来学习下. 1.两个对象的比较 Javascript的比较中参杂了一些比较奇怪的特性,我们来看一些比较简单的比较. // 原始值的比较 > var a = 12 undefined > var b = 12 undefined > a == b true > a === b true // 对象的比较 > var c = [] undefined > var d = [] undefin

  • Javascript类型系统之String字符串类型详解

    javascript没有表示单个字符的字符型,只有字符串String类型,字符型相当于仅包含一个字符的字符串 字符串String是javascript基本数据类型,同时javascript也支持String对象,它是一个原始值的包装对象.在需要时,javascript会自动在原始形式和对象形式之间转换.本文将介绍字符串String原始类型及String包装对象 定义 字符串String类型是由引号括起来的一组由16位Unicode字符组成的字符序列 字符串类型常被用于表示文本数据,此时字符串中的

  • 用javascript打造搜索工具栏

    一:最终效果 二:原理 如果你在Yahoo中搜索"中国",那么在浏览器的地址栏将得到这样一串地址:http://search.cn.yahoo.com/search?ei=gbk&fr=fp-tab-web-ycn&meta=vl%3Dlang_zh-CN%26vl%3Dlang_zh-TW&pid=ysearch&source=ysearch_www_hp_button&p=%D6%D0%B9%FA&Submit=看上去有些乱了,简化一

随机推荐