建议8:谨慎使用运算符(1)
1.用===,而不用==
JavaScript有两组相等运算符:===和!==、==和!=。===和!==这一组运算符会按照期望的方式工作。如果两个运算数类型一致且拥有相同的值,那么===返回true,而!==返回false。==和!=只有在两个运算数类型一致时才会做出正确的判断,如果两个运算数是不同的类型,会试图强制转换运算数的类型。转换的规则复杂且难以记忆,具体规则如下:
- '' == '0' // false
- 0 == '' // true
- 0 == '0' // true
- false == 'false' // false
- false == '0' // true
- false == undefined // false
- false == null // false
- null == undefined // true
上面表达式如果全部使用===运算符,则都会返回true。
==和!=运算符缺乏传递性,需要引起警惕。所谓传递性就是:如果a==b为true,b==c为true,则a==c也为true。因此,在JavaScript开发中,建议永远不要使用==和!=,而选用===和!==运算符。
下面分别介绍一下===和==运算符的算法。
(1)===运算符的算法
在使用===来判断两个值是否相等时,如判断x===y,会先比较两个值的类型是否相同,如果不相同,直接返回false。如果两个值的类型相同,则接着根据x的类型展开不同的判断逻辑:
如果x的类型是Undefined或Null,则返回 true。
如果x的类型是Number,只要x 或y中有一个值为NaN,就返回 false;如果x和y的数字值相等,就返回 true;如果x或y中有一个是+0,另外一个是–0,则返回 true。
如果x的类型是String,当x和y的字符序列完全相同时返回 true,否则返回 false。
如果x的类型是Boolean,当x和y同为true或false时返回 true,否则返回 false。
当x和y引用相同的对象时返回 true,否则返回 false。
(2)==运算符的算法
在使用==来判断两个值是否相等时,如判断x==y,如果x和y的类型一样,判断逻辑与=== 一样;如果x和y的类型不一样,==不是简单地返回false,而是会进行一定的类型转换。
如果x和y中有一个是 null,另外一个是undefined,返回true,如null == undefined。
如果x和y中有一个类型是String,另外一个类型是Number,会将String类型的值转换成 Number来比较,如3 == "3"。
如果x和y中有一个类型是Boolean,会将Boolean类型的值转换成Number来比较,如true == 1、true == "1"。
如果x和y中有一个类型是String或Number,另外一个类型是Object,会将Object类型的值转换成基本类型来比较,如[3,4] == "3,4"。
2.谨慎使用++和--
递增(++)和递减(--)运算符使程序员可以用非常简洁的风格去编码,如在C语言中,它们使得通过一行代码实现字符串的复制成为可能,例如:
- for (p = src, q = dest; !p; p++, q++) q = *p;
事实上,这两个运算符容易形成一种不谨慎的编程风格。大多数的缓冲区溢出错误所造成的安全漏洞都是由于这种编码导致的。
当使用++和--时,代码往往变得过于紧密、复杂和隐晦。因此,在JavaScript程序设计中不建议使用它们,从而使代码风格变得更为整洁。