先看看if中的真假
各种值在if中的真假
undefined //false
1//true
-1//true
0.0//false
-0//false
0//false
NAN//false
Infinity//true 这竟然是真
''//false
'1'//true
'0'//true
[]//true
{}//true
null//false
function() {}//true
(function() {}())//false 函数默认返回undefined
Symbol(0)//true
结论
- undefined,0,NAN,’’,null,只有这五位为false
- 不管是0,0.0,0.00或者-0,只要最终是0都为假
而!与if内的判断刚好相反
所以if()内都可以用!来反转判断真假
再看看==(双等号) 与 ===(三等号)
一一举例的话案例就太多了,就直接说结论吧
严格运算符 === 的判断比较简单:
1、类型不同就为假
2、类型相同基本类型看值,引用类型看地址(以下都为双方类型相同的情况)
- number类型:最终值完全相同则为真,比如00===0 //true (除了NAN,虽然它也为number类型,但
NAN ===NAN
为假,Infinity也为number类型但Infinity === Infinity
为真) - string类型: 值完全相同则为真
- 引用类型:地址完全相同则为真
- null: 相同
- undefined:相同
再看看==(双等号)的
不想看通篇长论的话可以看看写一个方法,实现 javascript 中双等号==的效果,双等于底层逻辑这个,直接上代码。
1、类型相同的情况下与严格相等的判定条件一样
2、以下为双方类型不同的情况下的判定
- 只要一方的值为
number
类型的值时,这一方不变,另一方不管是谁(除了null
,undefined
),都得最终都得用Number()
方法转换后比较,以下几条都遵循第一条的定律 Boolean
与任何类型比较时,用Number()
事先转化成Number
类型再比较,所以任何值与Boolean
比较都等同于与Number
类型比较。null
与undefined
相互比较时为 true ,他俩与其他类型比较都为 false 。- 只有一方有引用类型时,先使用
valueOf()
,再使用toString()
转换为字符串比较,双等号中除了date
优先使用toString()
(所以有一篇博文说只用 valueOf 其实不对,不过 toString 也有点玄学下一篇会说)。
以下是 2019年5月的新编辑(新的理解)。现在我们使用js引擎中抽象操作的逻辑来验证一下前面双等于的总结。
我们先来看一下两个抽象操作。
toNumber()
与Number()
一样。只不过如果传入一个对象时,则结果为Number(toPrimitive(obj))
toPrimitive()
如果想通过它转化的类型为Number
类型(默认),先计算obj.valueOf(),如果结果为原始值,则返回此结果;否则.执行obj.toString()
,如果结果是原始值,则返回此结果;否则,抛出异常.如果传入对象为date
则默认为想转化成String
类型,也就是先用toString
,再用valueOf
。
下面为双等于
的逻辑——
首先是null
,undefined
与各种类型的比较(优先级别一也就是优先执行这个逻辑代码
)
相比较对象类型 | 其操作逻辑 (输出) | 相比较我们的总结 |
---|---|---|
各类型 | 直接返回false | 符合第3条 |
首先是Number
类型与各种类型的比较中,相应的转换。以下设y为自身,x为相比较的对象。(优先级别三最后执行
)
相比较对象类型 | 其操作逻辑(输出) | 相比较我们的总结 |
---|---|---|
各类型 | toNumber(x)后进行比较 | 符合第1条 |
再看一下 Boolean
类型与各种类型的比较中,各类型的转换。(优先级别二)
相比较对象类型 | 其操作逻辑(输出) | 相比较我们的总结 |
---|---|---|
各种类型 | 先toNumber(y)后进行比较 | 符合第2条 |
再看一下引用
类型与各种类型的比较中,各类型的转换。(优先级别二)
相比较对象类型 | 其操作逻辑 (输出) | 相比较我们的总结 |
---|---|---|
各种类型 | 先toPrimitive(y)后进行比较 | 符合第4条 |
只要跟着上面的路子走就能很好地判断==
与===
的使用了,但是如果在多人开发中,使用了== 最好加上点注释,因为无意的==
会让读你代码的人耗好多脑子
举个例子[]==false//true
中按照第四条规律用toString()
变为 ''空字符串,空字符串在与boolean
比较时用第二条定律用Number()
,Number('')
为0,Number(false)
也为0。当两者类型相等时,使用 ===
判断,0对比0见三等于的第一种规律,所以也为0
第二个例子function () { } == 'function () { }'//true
,也是引用类型,会用第四条定律使用toString转成字符串再与'function () { }'
相比较,两个字符串比较看严格等于的第二条,所以也为真
记得阿里面试有一道题目 写一个对象A,使 A == '1'
,这时候就有思路了对不对,A在转换的时候就会使用valueOf
和toString
,我们只要将其中一个 重写一下,加个return '1'
不就完事了吗。
也可以 let A = new Array['1'] ; A =='1'//true
至于arr.toString()
会变成什么样详解valueOf和toString会详细讲到
但是,现在问题来了
下列图片中只有第一个为true
其余四个都为false
这咋回事呢,请听下回分解哈哈
然后来看看Number()方法
Number(true)//1
//以下省略Number函数
false//0
{}//NaN
{ name: '1' }//NaN
[undefined]//0
[null]//0
[]//0
[1]//1
[2]//2
['1']//1
[true]//NaN
''//0
'0'//0
'1'//1
'1abc'//NaN
'abc1'//NaN
0123//123
null//0
undefined//NaN
Symbol(1)//直接报错
0.00000//0
0.00001//0.00001
-0//-0包括Infinity和NaN,除了0.000外都是等值输出
总结,
- number类型除了0.00外其他原样输出
- string类型如果内容只有数字的话数字原样输出,如果为空字符串,则输出0;如果有其他字符则输出NaN,如果前面有0,则去掉比如0123转为123,如果有16位进制数则转成十进制,如果为空则输出0
- 如果是引用对象,先使用valueOf(),再使用toSting()后再按照上面两条规则进行转换