js 隐式类型转换

关系操作符(<, >, <=, >=)

与上述操作符一样,关系操作符的操作值也可以是任意类型的,所以使用非数值类型参与比较时也需要系统进行隐式类型转换:
(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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,598评论 25 708
  • 前言 平时我们看到一些应用程序里面有很多漂亮的小图标,我们也想用怎么办???,别急,我有办法,咱们可以通过iToo...
    IIronMan阅读 1,719评论 2 3
  • 我想写诗 写一首值得称赞的诗 像李白一样浪漫洒脱 或像杜甫般沉郁顿挫 提起笔来却挤不出墨水 一声叹息 叹的是平淡岁...
    东惑不祢阅读 656评论 1 2