详解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 相关文章推荐
基于jquery的滚动条滚动固定div(附演示下载)
Oct 29 Javascript
不要使用jQuery触发原生事件的方法
Mar 03 Javascript
文本域光标操作的jQuery扩展分享
Mar 10 Javascript
javascript判断是手机还是电脑访问网页的简单实例分享
Jun 03 Javascript
javascript中createElement的两种创建方式
May 14 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
Aug 03 Javascript
zTree树形插件异步加载方法详解
Jun 14 Javascript
vue.js实现只弹一次弹框
Jan 29 Javascript
对vux点击事件的优化详解
Aug 28 Javascript
在layui下对元素进行事件绑定的实例
Sep 06 Javascript
vue跳转页面的几种方法(推荐)
Mar 26 Javascript
JS pushlet XMLAdapter适配器用法案例解析
Oct 16 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
php中文字母数字验证码实现代码
2008/04/25 PHP
php流量统计功能的实现代码
2012/09/29 PHP
PHP和Shell实现检查SAMBA与NFS Server是否存在
2015/01/07 PHP
浅谈PHP命令执行php文件需要注意的问题
2016/12/16 PHP
发两个小东西,ASP/PHP 学习工具。 用JavaScript写的
2007/04/12 Javascript
jQuery lazyload 的重复加载错误以及修复方法
2010/11/19 Javascript
在JavaScript中获取请求的URL参数[正则]
2010/12/25 Javascript
javascript实现yield的方法
2013/11/06 Javascript
jQuery select表单提交省市区城市三级联动核心代码
2014/06/09 Javascript
node.js中的http.request方法使用说明
2014/12/14 Javascript
jquery通过ajax加载一段文本内容的方法
2015/01/15 Javascript
JS使用cookie实现DIV提示框只显示一次的方法
2015/11/05 Javascript
jQuery中队列queue()函数的实例教程
2016/05/03 Javascript
js简单判断flash是否加载完成的方法
2016/06/21 Javascript
js中获取 table节点各tr及td的内容简单实例
2016/10/14 Javascript
jQuery实现导航回弹效果
2017/02/27 Javascript
微信小程序实现选项卡功能
2020/06/19 Javascript
vue 表单验证按钮事件交由父组件触发的方法
2018/12/17 Javascript
微信小程序模板消息推送的两种实现方式
2019/08/27 Javascript
ES6中Set和Map用法实例详解
2020/03/02 Javascript
利用js canvas实现五子棋游戏
2020/10/11 Javascript
react-native 实现购物车滑动删除效果的示例代码
2021/01/15 Javascript
python机器学习理论与实战(五)支持向量机
2018/01/19 Python
使用python获取csv文本的某行或某列数据的实例
2018/04/03 Python
PYQT5设置textEdit自动滚屏的方法
2019/06/14 Python
opencv调整图像亮度对比度的示例代码
2019/09/27 Python
Python OpenCV读取显示视频的方法示例
2020/02/20 Python
解决django的template中如果无法引用MEDIA_URL问题
2020/04/07 Python
《都江堰》教学反思
2014/02/07 职场文书
捐助贫困学生倡议书
2014/05/16 职场文书
股份转让协议书范本
2015/01/27 职场文书
部门经理迟到检讨书
2015/02/16 职场文书
Java实现简易的分词器功能
2021/06/15 Java/Android
详解Java实现设计模式之责任链模式
2021/06/23 Java/Android
Android存储中最基本的文件存储方式
2022/04/30 Java/Android
Python Flask实现进度条
2022/05/11 Python