JavaScript 中大概有这几种 “范例”:
undefined
null
string
boolean
number
object
function
之所以在 “范例” 上加了双引号,是因为严厉来说,null 的范例是 object。但本文议论的主题包含了关于 null 的范例转换,它和 object 差别,所以零丁列出来了。这点请依据上下文强行辨别一下,不是bug、不是bug、不是bug。
风趣的例子
'0' == 0; // true
0 == ''; // true
'0' == ''; // false
这里展现的是相称比较的非传递性。即,假如有 a == b, b == c,并不代表 a == c。
假如说
'1' == true;
'0' == false;
这两个是基础知识,那关于一些特别的字符串,你能准确推断吗?
'001' == true;
'002' == false; // 注重!
'0x0' == false;
'\n' == false;
非严厉相称(==)
当运用 == 比较,而且两侧的范例差别时,会触发隐式范例转换。规范中定义的转换划定规矩很长,其中心就是,1、范例差别时,只管转成 数字 比较;2、惯例。(范例雷同就按该范例的值推断,不特别说清楚明了,岂非 ‘123’ 还能即是 ‘456’ 不成?)
关于惯例,实在也就是 null 和 undefined 。也就是说,以下几个表达式是永远为 true 的。
undefined == null;
null == undefined;
NaN != NaN; // 注重!
null != 非null; // 注重!null 与非 null 值永远是不等的
所以也不须要再去深追为何 undefined 和 null 是相称的,因为根据“划定规矩”已无法解释了,这是一种“商定”。OK,剩下的状况是转数字。
null 的数值是 0
undefined 的数值是 NaN
true 是 1,false 是 0
至于字符串,嗯,有点庞杂
object:挪用 toString 或 valueOf 后转成基础范例,再转数字
第一条,在这里没用,因为涉及到 null 的比较时,除非 null == null,其他状况都是不等的。即
null != 0;
第二条,在这里没用,因为涉及到 NaN 的比较时,都是不等。
第三条,有点用,很有效!
1 == true; // 对
2 == true; // 错!
第四条,贫苦。80% 状况下,关于 ‘123’ 转成 123,’abc’ 转成 NaN,” 转成 0,这三条记着就能够了。
'123' == 123;
'' == 0;
'abc'; // 转成数值是 NaN
别的的状况,因为字符串的组合情势林林总总,很难一言半语总结完,大抵有:
空缺字符串转成 0,’\n’ == 0
十六进制、八进制一般转换,’0xff’ == 255
数字字符串会疏忽首尾空缺字符,一般转,’\n123\n’ == 123
数字字符和其他字符混应时,转成 NaN,如 ‘123abc’
如今转头去看“风趣的例子”,是不是是一览无余。(嗯,不谢)
前提推断
临时把 if – else 和 condition ? a : b; 中的推断状况称为前提推断吧。(场景另有取反、for、while 等)
即是 true 的值一定是 truthy,但即是 false 的值不一定是 falsy 。
例
new Boolean(false) == false; // 这个没问题吧?
new Boolean(false) ? 'a' : 'b'; // 表达式的值是 'a'!
只能说,前提推断中对真假的剖断和相称推断是不一样的。 明显,相称推断是基于数字比较的,而前提推断是基于布尔值。
关于布尔值的转换划定规矩:
null, undefined, NaN 都是 false
字符串,仅当空字符串(”)时为 false,其他都是 true
object,都是 true (仅 null 除外)
我见过其他一些相称推断的技能:
!!x == true;
+x == 123;
取反操纵会把变量强转成 boolean;一元 + 会把变量强转成 number。
也见过一些用的不太适宜的处所(?):
if (!!x) // ...
在前提推断中自身会做强转的操纵,为了可读性?不见得有进步。
严厉相称(===)
严厉相称的逻辑相对简朴粗犷,假如范例差别,就不斟酌隐式转换了,直接为假。假如范例雷同:
布尔、数字、字符串就看字面值是不是相称
object,看援用是不是雷同
主如果斟酌什么时候用 ==,什么时候用 === 。
很简朴,只要在请求范例雷同时,才用 ===,否则用 ==
有些场景确实只要非严厉相称才能做,比方
var b = new Boolean(false);
b === false // 竟然是错的
b == false // 对
b ? 'a' : 'b' // 竟然是 'a'
结论就是当涉及到对象比较时,轻微斟酌一下。而关于像 typeof x 它一定会返回 string,这时候用 == 比较就更适宜一些。
小结
涉及到 == 比较,而且须要隐式转换时,会转成 number。
涉及到前提推断,自然是转成 boolean。
涉及到二元 +、- 等数值盘算时,从左至右优先转成 number,除非是碰到 string,则做字符串拼接操纵。