关系操作符(<, >, <=, >=)
与上述操作符一样,关系操作符的操作值也可以是任意类型的,所以使用非数值类型参与比较时也需要系统进行隐式类型转换:
(1)如果两个操作值都是数值,则进行数值比较
(2)如果两个操作值都是字符串,则比较字符串对应的字符编码值
(3)如果只有一个操作值是数值,则将另一个操作值转换为数值,进行数值比较
(4)如果一个操作数是对象,则调用valueOf()方法(如果对象没有valueOf()方法则调用toString()方法),得到的结果按照前面的规则执行比较
(5)如果一个操作值是布尔值,则将其转换为数值,再进行比较
注:NaN是非常特殊的值,它不和任何类型的值相等,包括它自己,同时它与任何类型的值比较大小时都返回false。
相等操作符(==)
相等操作符会对操作值进行隐式转换后进行比较:
(1)如果一个操作值为布尔值,则在比较之前先将其转换为数值
(2)如果一个操作值为字符串,另一个操作值为数值,则通过Number()函数将字符串转换为数值
(3)如果一个操作值是对象,另一个不是,则调用对象的valueOf()方法,得到的结果按照前面的规则进行比较
(4)null与undefined是相等的
(5)如果一个操作值为NaN,则相等比较返回false
(6)如果两个操作值都是对象,则比较它们是不是指向同一个对象
测试用例
function Person(){}
Person.prototype = {
toString() { return "ooo";},
valueOf() { return 123;}
}
var p = new Person() ;
// ️ result in chrome
可以看出,与前文所述隐式类型转换相符
BUG(或者说暂时未能完美解释的地方)
2019/8/02更新:不是bug,解释见文末
var date = new Date("1970/1/2 8:00:00");
date.valueOf() ; //console of Chrome : 86400000
date.toString(); //console of Chrome : "Fri Jan 02 1970 08:00:00 GMT+0800 (CST)"
// '<=' '<' '==' don't have self-consistent
date <= 86400000 //console of Chrome : true
date < 86400000 //console of Chrome : false
date == 86400000 //console of Chrome : false
// Oh! It's awesome!
//This make sense
date == date.toString() //console of Chrome : true
date <= date.toString() //console of Chrome : false
// Oh! It really make sense because 864000 <= "string" is equal to 864000 <= 0
所以总结一下
date 在遇到'<' '<='的时候会默认转换至.valueOf() ,
而它遇到 '==' 的时候明明有.valueOf()却还是选择转换为 .toString()
解决该疑惑可以看https://juejin.im/post/5a7172d9f265da3e3245cbca#heading-6
网友评论