谈谈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的朋友能够遵循这些规范,不要再受以前那些过时和被证实为有害的编码方式的毒害了。好了,今天就讲这么多吧!


猜你喜欢
- 1,判断图像清晰度,明暗,原理,Laplacian算法。偏暗的图片,二阶导数小,区域变化小;偏亮的图片,二阶导数大,区域变化快。import
- 1、把这段拷到DW里,存成HTML文件。<HTML><HEAD><TITLE>move backgrou
- pycurl是一个用c语言编写的libcurl Python实现,功能非常强大,支持操作协议有FTP,HTTP,HTTPS,TELNET等。
- 1 为什么需要防抖和节流在前端开发当中,有些交互事件,会被频繁触发,这样会导致我们的页面渲染性能下降,如果频繁触发接口调用的话,会直接导致服
- 前言tensorflow提供了多种读写方式,我们最常见的就是使用tf.placeholder()这种方法,使用这个方法需要我们提前处理好数据
- 0x01 安装pyinotify>>> pip install pyinotify>>> import
- 当我们建好数据库及表后,首先想到的就是向数据库的表中输入数据.下面我们就来探讨一下如何向数据库增加数据:1.常用的方法是insert语句in
- 最近在做编程练习,发现有些结果的值与答案相差较大,通过分析比较得出结论,大概过程如下:定义了一个计算损失的函数:def error(yhat
- 如果你使用的正是mysql数据库,那么你把密码或者其他敏感重要信息保存在应用程序里的机会就很大。保护这些数据免受黑客或者窥探者的获取是一个令
- 环境搭建准备工具:pyton3.5,selenium,phantomjs我的电脑里面已经装好了python3.5安装Seleniumpip3
- 一. 打印图片属性、设置图片存储路径代码如下:#打印图片的属性、保存图片位置import cv2 as cvimport nump
- 项目场景:最近在部署项目之后,运行出现报错:Expression #1 of SELECT list is not in GROUP BY
- 现在Go1.14都已经发布好些日子了,之前发的Go环境搭建教程早已过时,只是因为时间问题一直没来得及更新这次怀着愧疚的心情,在凌晨四点时,将
- 最近需要做一个表格样式,需要组合表头,现在把做出来的分享给大家, 1、效果图2、html代码 <table id="
- Hedger Wang 在国内 blog 上得到的方法:使用 try … finally 结构来使对象最终为 null ,以阻止内存泄露。其
- 环境 MySQL 5.1 + 命令行工具 问题 MySQL表字段设置默认值 解决 --SQL: CREATE TABLE test( i_a
- 代码如下:<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001&quo
- Oracle数据库在使用的过程中常常会遇到这样或那样的问题,而这些问题常常又使我们感到很困惑,本文我们总结了Oracle数据库在使用过程中的
- 一、为何人工智能(AI)首选Python?读完这篇文章你就知道了。我们看谷歌的TensorFlow基本上所有的代码都是C++和Python,
- python的注释方式和C语言、C++、java有所不同python语言中,使用‘#' 来进行注释,其次还有使用 三个引号来进行注释