(转)JavaScript中==等同运算符的类型转换

原文地址:http://liwenbing.cn/tag/javascript-equal-type-conversion/

这周在给一些新员工讲JavaScript的时候,谈了==和===的区别,本质来说,===是严格的等同运算符,要求两者类型相同并且值相同;而==运 算符在做比较时,会做一定的类型转换。我们在使用过程中应该使用===而不是==,因为这种类型转换后的比较往往都不是你想要的。当时列出了 corckfork最喜欢一些例子

'' == '0'          // false
	0 == ''            // true
	0 == '0'           // true
	false == 'false'   // false
	false == '0'       // true
	false == undefined // false
	false == null      // false
	null == undefined  // true
	' \t\r\n ' == 0    // true

转换规则

当时有人就问了,那么在做类型转换的时候倒是等式的左边向右边转,还是反过来呢?其实这些都是不对的,我们去看看ECMAScript的规范,会发现它有对于等同运算符做类型转换很明确的比较算法,下面我将其翻译如下:
对于比较x==y,

1.如果x和y类型不同,那么到14步;
//
//2-13步,为类型相同的比较
//
14.如果x是null,y是undefined,返回true;
15.如果x是undefined,y是null,返回true;
16.如果x是Number,y是String,将y转化成Number,然后再比较;
17.如果x是String,y是Number,将x转化成Number,然后再比较;
18.如果x是Boolean,那么将x转化成Number,然后再比较;
19.如果y是Boolean,那么将y转化成Number,然后再比较;
20。如果x是String或者Number,y是Object,那么将y转化成基本类型,再进行比较;
21.如果x是Object,y是String或者Number,将x转化成基本类型,再进行比较;
22.其他情况均返回false;

ECMA这帮人写的算法过程比较啰嗦,简单一句话来概括就是,对于基本类型Boolean,Number,String,三者之间做比较时,总是向 Number进行类型转换,然后再比较;如果有Object,那么将Object转化成这三者,再进行比较;对于null和undefined,只有 x,y分别是它们时才相同,其他都为false。

另外,对于转化到Number的算法,细节可以来看ECMAScript的规范,但是基本上下面这个几个表可以覆盖大部分的内容:

type-convert to number (+col) : String Values.
“”
(empty
string)
“-1.6″ “0″ “1″ “1.6″ “8″ “16″ “16.8″
+col 0 -1.6 0 1 1.6 8 16 16.8
type-convert to number (+col) : String Values.
“123e-2″ “010″
(Octal)
“0×10″
(Hex)
“0xFF”
(Hex)
“-010″ “-0×10″ “xx”
+col 1.23 10 16 255 -10 NaN NaN
type-convert to number (+col) : Other Values.
undefined null true false new Object() function(){
return;
}
+col NaN 0 1 0 NaN NaN

再回头来看看corkford给出的例子,然后使用上面的规则去判断;

'' == '0'          // false
//类型相同,毫无疑问,值不同,所以结果为false
 
0 == ''            // true
//String要像Number转化,''是空String,根据上面的表,转成0,所以结果是true
 
0 == '0'           // true
//String要像Number转化,根据上面的转化Number表,'0'转成0,所以结果是true
 
false == 'false'   // false
//有Boolean,转化成Number,所以第一步转化后为0=='false';
//然后'false'向Number转,结果是NaN,最后变成比较0==NaN,那么肯定是false。
//(NaN和任何相比都是false,就算是自己也是false, NaN==NaN //false)
 
false == '0'       // true
//有Boolean,转化成Number,经过第一次转化就成了0=='0';
//就变成了上面的第3个例子,所以是true
 
false == undefined // false
//对于undefined和null,只有两边分别是两者才是true,其他都是false;所以是false
 
false == null      // false
//对于undefined和null,只有两边分别是两者才是true,其他都是false;所以是false
 
null == undefined  // true
//对于undefined和null,只有两边分别是两者才是true,其他都是false;所以是true
 
' \t\r\n ' == 0    // true
//对于String,先转成Number,对于空String,都将转成0,所以转化后成为0==0,结果为true
//(注意,空字符不仅仅是只是空格,还包括\t\r\n等等,更多可以见ECMAScript spec的9.3.1)

总结

虽然我们了解了==这个坏东西的本质,但是在我们的实际JavaScript编程中是要避免使用==,而是去使用===这个严格的比较运算符。

转载于:https://my.oschina.net/huawu/blog/7654

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值