朋友问我false == null => false 而不是 true
我们先明确 == 弱类型比较 === 是强类型比较
== 会进行类型转换再进行比较
=== 不会进行类型转换 先比较类型 后比较值
问题就出在 == 的时候,developer会认为 false 就是布尔类型,只需要把右侧的转换成布尔类型就可以了
会出现 Boolean(null) =>false false == false => true
敲重点
“==” 比较中,不同类型 比较时,字符串、boolean会先转换成数值类型再进行判断。对象会先转换为原始值在进行比较!
再看上面的例子
Number(false) => 0
typeof null => "object"
我们先理解对象类型如何转换成原始值 这里针对 false == null的例子
对象到 数字类型 的转换过程中,先调用valueOf()方法,如果返回值是基础数据类型,则进行比较,否,则调用toString()
实例:
var obj = {
toString:()=>{
return 1
},
valueOf:()=>{
return 0
}
}
obj == false =>true
obj.valueOf() == false => true
obj.toString() == false => false
复制代码
反向证明:为什么先调用valueOf()再调用toString():
Number(false)=>0
obj.valueOf() => 0
obj.toString() => 1
因为 obj == false =>true 所以 先调用valueOf()方法,一旦返回值为基础类型则进行比较
结论很明显
因为null类型本身不具备valueOf 或者是 toString()方法
Object.prototype.valueOf.call(null)
这里throw error
Uncaught TypeError: Cannot convert undefined or null to object
原因
This error is caused when you call a function that expects an Object as its argument,
but pass undefined or null instead, like for example
调用一个方法,希望参数是object 但是实参为null或者是undefined
其他错误例子
object.keys(null)
推论:
var fun = Object.prototype.valueOf,var obj={}
fun.call({}).toString() == obj.valueOf().toString() =>true
换toString
Object.prototype.toString.call(null) => "[object Null]"
结果
Number("[object Null]") => NaN
"[object Null]" == 0 =>false
复制代码
这里强调下 这是对象转换成数字类型的转换顺序
如果是对象转换成字符串比较先调用toString()方法,再调用valueOf()方法
推荐
《JavaScript 权威指南》(原书第六版) 作者 弗兰纳根 *** 划重点 多动手