详解JavaScript中双等号引起的隐性类型转换


Posted in Javascript onMay 30, 2016

引子

if语句应该是程序员用的比较多的语句,很多时候都要进行if判断,if语句一般用双等号来判断前后两个元素是否是一致的,假如是一致,那么返回是true,然后执行下面的语句,否则,执行别的语句。本文所说的隐性类型的转换,说的是==引起的转换。举个简单的例子,双等号不是全等号,全等号是“===”三个等号,语句"1"==1,那么一般情况下是前面的字符串”1“转换为数字1,然后进行比较。通过这个例子应该了解了什么是隐性类型的转换了吧!

隐性类型转换步骤

一、首先看双等号前后有没有NaN,如果存在NaN,一律返回false。

二、再看双等号前后有没有布尔,有布尔就将布尔转换为数字。(false是0,true是1)

三、接着看双等号前后有没有字符串, 有三种情况:

1、对方是对象,对象使用toString()或者valueOf()进行转换;
2、对方是数字,字符串转数字;(前面已经举例)
3、对方是字符串,直接比较;
4、其他返回false
四、如果是数字,对方是对象,对象取valueOf()或者toString()进行比较, 其他一律返回false

五、null, undefined不会进行类型转换, 但它们俩相等

上面的转换顺序一定要牢记,面试的时候,经常会出现类型的问题。

.toString()方法和.valueOf()方法数值转换

通常情况下我们认为,将一个对象转换为字符串要调用toString()方法,转换为数字要调用valueOf()方法,但是真正应用的时候并没有这么简单,看如下代码实例:

var obj = {
 webName: "haorooms前端博客",
 url:"3water.com"
}
console.log(obj.toString()); //[object Object]

同理,我们再看valueOf()方法:

var arr = [1, 2, 3];
console.log(arr.valueOf());//[1, 2, 3]

从上面的代码可以看出,valueOf()方法并没有将对象转换为能够反映此对象的一个数字。相反,我们用toString()

var arr = [1, 2, 3];
console.log(arr.toString());//1,2,3

注:很多朋友认为,转换为字符串首先要调用toString()方法, 其实这是错误的认识,我们应该这么理解,调用toString()方法可以转换为字符串,但不一定转换字符串就是首先调用toString()方法。

我们看下下面代码:

var arr = {};
arr.valueOf = function () { return 1; }
arr.toString = function () { return 2; }
console.log(arr == 1);//true

var arr = {};
arr.valueOf = function () { return []; }
arr.toString = function () { return 1; }
console.log(arr == 1);//true

上面代码我们可以看出,转换首先调用的是valueOf(),假如valueOf()不是数值,那就会调用toString进行转换!

var arr = {};
arr.valueOf = function () { return "1"; }
arr.toString = function () { return "2"; }
console.log(arr == "1");//true

假如"1"是字符串,那么它首先调用的还是valueOf()。

var arr = [2];
console.log(arr + "1");//21

上面的例子,调用的是toString();因为arr.toString()之后是2。

转换过程是这样的,首先arr会首先调用valueOf()方法,但是数字的此方法是简单继承而来,并没有重写(当然这个重写不是我们实现),返回值是数组对象本身,并不是一个值类型,所以就转而调用toString()方法,于是就实现了转换为字符串的目的。

小结

大多数对象隐式转换为值类型都是首先尝试调用valueOf()方法。但是Date对象是个例外,此对象的valueOf()和toString()方法都经过精心重写,默认是调用toString()方法,比如使用+运算符,如果在其他算数运算环境中,则会转而调用valueOf()方法。

var date = new Date();
console.log(date + "1"); //Sun Apr 17 2014 17:54:48 GMT+0800 (CST)1
console.log(date + 1);//Sun Apr 17 2014 17:54:48 GMT+0800 (CST)1
console.log(date - 1);//1460886888556
console.log(date * 1);//1460886888557
Javascript 相关文章推荐
网页中实现浏览器的最大,最小化和关闭按钮
Mar 12 Javascript
AngularJS + Node.js + MongoDB开发的基于高德地图位置的通讯录
Jan 02 Javascript
javascript中Object使用详解
Jan 26 Javascript
JavaScript中的值是按值传递还是按引用传递问题探讨
Jan 30 Javascript
jQuery获取file控件中图片的宽高与大小
Aug 04 Javascript
js显示动态时间的方法详解
Aug 20 Javascript
jQuery实现最简单实用的分秒倒计时
Feb 05 Javascript
Bootstrap模态框案例解析
Mar 05 Javascript
改变vue请求过来的数据中的某一项值的方法(详解)
Mar 08 Javascript
如何进行微信公众号开发的本地调试的方法
Jun 16 Javascript
详解基于 Node.js 的轻量级云函数功能实现
Jul 08 Javascript
Antd下拉选择,自动匹配功能的实现
Oct 24 Javascript
JavaScript中的操作符类型转换示例总结
May 30 #Javascript
jQuery中的通配符选择器使用总结
May 30 #Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
May 30 #Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
May 30 #Javascript
使用jQuery判断浏览器滚动条位置的方法
May 30 #Javascript
JS检测移动端横竖屏的代码
May 30 #Javascript
BootStrap中Tab页签切换实例代码
May 30 #Javascript
You might like
Discuz! Passport 通行证整合
2008/03/27 PHP
PHP按指定键值对二维数组进行排序的方法
2015/12/22 PHP
php字符串比较函数用法小结(strcmp,strcasecmp,strnatcmp及strnatcasecmp)
2016/07/18 PHP
php之可变变量的实例详解
2017/09/12 PHP
jquery模拟SELECT下拉框取值效果
2013/10/23 Javascript
Javascript中浮点数相乘的一个解决方法
2014/06/03 Javascript
详解JavaScript语法对{}处理的坑爹之处
2014/06/05 Javascript
js 操作符汇总
2014/11/08 Javascript
兼容Firefox的Javascript XSLT 处理XML文件
2014/12/31 Javascript
jQuery调用ajax请求的常见方法汇总
2015/03/24 Javascript
jQuery的几个我们必须了解的特点
2015/05/03 Javascript
微信小程序 window_x64环境搭建
2016/09/30 Javascript
js实现可旋转的立方体模型
2016/10/16 Javascript
canvas学习之API整理笔记(二)
2016/12/29 Javascript
angular.JS实现网页禁用调试、复制和剪切
2017/03/31 Javascript
jquery实现tab选项卡切换效果(悬停、下方横线动画位移)
2017/05/05 jQuery
原生js轮播特效
2017/05/18 Javascript
最常用的jQuery表单验证(简单)
2017/05/23 jQuery
浅析webpack 如何优雅的使用tree-shaking(摇树优化)
2017/08/16 Javascript
keep-alive不能缓存多层级路由菜单问题解决
2020/03/10 Javascript
[02:37]2018DOTA2亚洲邀请赛赛前采访 VP.no[o]ne心中最强SOLO是谁
2018/04/04 DOTA
[03:17]史诗级大片应援2018DOTA2国际邀请赛 致敬每一位坚守遗迹的勇士
2018/07/20 DOTA
[51:53]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第二场 11.01
2020/11/02 DOTA
Python判断操作系统类型代码分享
2014/11/22 Python
Django中的“惰性翻译”方法的相关使用
2015/07/27 Python
浅谈Python中的zip()与*zip()函数详解
2018/02/24 Python
解决pycharm 远程调试 上传 helpers 卡住的问题
2019/06/27 Python
tesserocr与pytesseract模块的使用方法解析
2019/08/30 Python
python 画函数曲线示例
2019/12/04 Python
一款纯css3实现的鼠标悬停动画按钮
2014/12/29 HTML / CSS
Linux面试经常问的文件系统操作命令
2016/10/04 面试题
工地安全检查制度
2014/02/04 职场文书
小学生新年寄语
2014/04/03 职场文书
党员承诺书怎么写
2014/05/20 职场文书
幼儿园安全教育月活动总结
2015/05/08 职场文书
2015年社区教育工作总结
2015/05/13 职场文书