谈谈Javascript中的++和–操作符
作者:海啸 来源:Yaohaixiao’s Blog 发布时间:2009-05-08 11:43:00
前两天有一位网友问我一个关于Javascript中++操作符的问题,他的代码大致是这样的
ADS.addEvent(window,'click',function(){
function modifiedAddEvent(obj,type,fn){
if(obj.addEventListener){
obj.addEventListener(type,fn,true);
}
else{
if(obj.attchEvent){
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn](window.event)};
obj.attchEvent('on'+type, obj[type+fn]);
}
else{
return false;
}
}
};
var counter = 0;
var lists = document.getElementsByTagName('ul');
for(var i=0;i
这段代码是《Javascript DOM高级编程》一书里的。其实这段代码主要是考察的不同的浏览起事件触发的模型不一样(IE中使用冒泡,FF中使用事件捕获,而我们的W3C标准则是先捕获再冒泡)。但他的问题是,为什么counter++的结果是从零开始的。而他希望的计算结果是从1开始计数。而他说,如果他这么写:
...
modifiedAddEvent(lists[i],'click',function(){
counter++;
var append = document.createTextNode(':' + counter);
this.getElementsByTagName('p')[0].appendChild(append);
this.className = 'clicked';
});
...
就可以得到他期望从1开始计数。其实产生这个问题是由于“++”后增量操作符的特性引起的。
这里我们有朋友可能在书中也看到过这么些的++counter,这里的“++”为前增量操作符。其实如果按照我的这个网友的想法,期望的从1开始计数的效果,应该使用前增量操作符就可以解决。
...
modifiedAddEvent(lists[i],'click',function(){
var append = document.createTextNode(':' + ++counter);
this.getElementsByTagName('p')[0].appendChild(append);
this.className = 'clicked';
});
...
那么前增和后增有什么区别吗?让我们来开看下面两段代码吧:
var counter = 0;
++counter;
alert(counter); // output 1
alert(++counter); // output 2
alert(counter) // output 2 var counter = 0;
counter++;
alert(counter); // output 1
alert(counter++); // output 1
alert(counter) // output 2
看出却别了吗?呵呵,原来前增量操作符的作用是在原来的基础上+1并同时将值付值给变量。
所以++counter就等价于counter = counter + 1,这么写大家估计就很清楚了(原来的基础上+1并同时将值付值给变量)。
而后增则不一样,它是在计算过包含它的表达式之后才进行增加的运算。这也是为什么这么写:
...
modifiedAddEvent(lists[i],'click',function(){
counter++; // 先计算过counter++表达式
var append = document.createTextNode(':' + counter); // 之后才能获得+1的运算结果
this.getElementsByTagName('p')[0].appendChild(append);
this.className = 'clicked';
});
...
可以达到这位网友的期望结果的原因。那么,我们“–”跟“++”拥有相同的特性我就不重复了。其实这个特性在《Javascript高级程序设计》一书的”ECMAScript基础”章节中已经做了详细的介绍了。而且也给出了两外一个有趣的问题的解释,我这里就给段代码:
var sNum = "25";
alert(typeof sNum); // output string
sNum = +sNum;
alert(typeof sNum); // output number
呵呵,这个我也不多重复了,大家看书吧。这个也是我为什么在我之前文章中推荐用这本书做javascript入门的基础教程原因,这本书中对Javascript基础知识的介绍我觉得跟其它的介绍javascript的书相比应该是十分详细的。好了,转到我们的主题,我这里要说一下,虽然我介绍了前增、后增操作符的特性,但是我并不推荐大家使用它。这里要我引用Crockford先生在《Javascript:The Good Parts》一书中的一段话:
The ++(increment) and –(decrement) operators have been known to contribute to bad code by encouraging excessive trickiness. They are second only faulty architecture in enabling viruses and other security menaces.
大致意思是++和–操作符号是不好的代码方式,会给你的程序带来安全问题。而我认为Crockford先生这句的理解是:1. 使用++或者–操作符,代码的可读性不好。2.使用++或者–操作符,可能会得不到你期望的结果,而导致程序错误,非常危险。
对了补充说明一下,++和–操作符号是直接借鉴的C和JAVA的语法,可能在C语言里,还鼓励你些类似这样的代码:
for(p=src,q=dest;!*p;p++,q++)*q=*p
但是Crockford先生实践的经验是:
Most the buffer overrun bugs that created terrible security vulnerabilities were due to code like this.
In my own practice, I observed that when I used ++ and –, my code tended to be too tight, too tricky, too cryptic. So, as a matter of discipline, I don’t use them any more.I think that as a result, my coding style has become cleaner.
所以Crockford先生也在《Javascript:The Good Parts》书中给出了替代++和–操作符的解决办法,那就是使用+=(加法/付值)和-=(减法/付值),不过在我看最近的YUI2.7,发现YAHOO的代码风格更倾向这么写:
counter = counter + 1; // 非常直观,可读性也最好。
所以这里我建议大家遵循的一个javascript代码规范就是:不要使用++和–操作符,请使用+=(加法/付值)和-=(减法/付值),或者最好这么写counter = counter + 1。
最后再多说两句,其实在我们平时(以前)的Javascript代码书写规范中,我们习以为常的很多的写法都是不好的,甚至是有害的。我就发现有很多的在BI发帖的朋友不知道是从哪里学来的Javascript编码规范,有的代码看得让我吐血。我就看到过有朋友使用变量从来不使用“var”关键字声明,而且更甚者居然使用eval来做数据类型转换(这个是最让我吐血的,我在某本介绍AJAX的书中也看到教人用eval做数据类型转换)。太恐怖了!我会在以后的文章中介绍一些Javascript的编码规范(其实YAHOO的工程师已经写了篇文章),来谈谈我对这些规范的理解,也希望刚开始接触Javascript的朋友能够遵循这些规范,不要再受以前那些过时和被证实为有害的编码方式的毒害了。好了,今天就讲这么多吧!
猜你喜欢
- SWFObject的使用是非常简单的,只需要包含 swfobject.js这个js文件,然后在DOM中插入一些简单的JS代码,就能嵌入Fla
- 无聊的人在无聊的时间做无聊的事打发自己,结果在无聊的事情中发现了IE对内联文字解释的一些疑惑。以下问题在FF2中没发现,而我也只
- 众所周知,IE 6只支持单通道的PNG图片(即只有透明/不透明2种状态,gif图片的透明单通道透明),因此如果需要使用alpha透明的png
- 本文主要介绍了一个获得当前数据库对象依赖关系的实用算法,具体示例请大家参考下文:create function&nb
- MySQL使用环境变量TMPDIR的值作为保存临时文件的目录的路径名。如果未设置TMPDIR,MySQL将使用系统的默认值,通常为/tmp、
- 背景:Email地址存于MSSql一用户信息表中,数量上万。公司自有服务器,集SMTP,POP3,WWW,FTP,MSSql,DNS等多种服
- 本文重在实践和测试,如果你还不了解Data URI,推荐先阅读秦歌的Data URI 和 MHTML。旺旺点灯(JS)实践经过:因为要对SR
- <% dim result,result1 str="ad_asp之家_nzlkjlkfjoj
- 首先说明下范围用Javascript来开发WEB页面的动画效果该思路同时考虑页面效率、SEO,如果数据大,也可以缓解后端压力。这个是程序设计
- 在不久前的一天,当我为了解决一个语法问题来翻阅VBscript文档时,偶然间发现在了下面的一句话: &nb
- CSS styles和HTML styles有什么区别?HTM style是指自定义HTML标识中一些标签,例如说在HTML中〈B〉〈/B〉
- 首先说明一下SQL Server内存占用由哪几部分组成。SQL Server占用的内存主要由三部分组成:数据缓存(Data Buffer)、
- 我认为在ASP中最好的办法是用编程实现定时刷新Cache,也就是说给Application中储存的设一个过期时间。当然,在ASP中Appli
- ASP中的全角和半角转化函数,使用方法,传入要转换的字符给str即可,flag设置要转换的类型。<% Function&n
- Doug Bowman,Google的Visual Design Lead离职了,一封带有感 * 彩的离职信惹发了大家不少的讨论。甚至还有人用
- [本站原创]在我们浏览了一些网页时,经常会弹出一些信息窗口或浏览器窗口以显示一些公告内容,想知道这些窗口是怎么制作出来的吗?如果你还不曾知道
- 看到这个需求的时候就在暗爽,又可以搞定一个知识点了。哈哈,一天的奋斗之后,果然有所收获,而且经过怿飞的指点,在跨域问题解决上还有所突破(不通
- 开源的MySQL并不能取代非共享的私有数据库在企业中的应用,于是这些开源数据库的支持者们想把解决Web应用程序开发工具的可扩展性问题看作是获
- ASP开发中有用的函数(function)集合,挺有用的,请大家保留!'******************************
- 具体特征如下: 1、通过模板实现俄文正常。 2、通过后台数据库生成的静态俄文信息,后台显示正常, 前台乱码。 3、英文正常。 和该主题相关的