JavaScript中三个等号和两个等号你了解多少


Posted in Javascript onJuly 04, 2017

引子

众所周知,用在if条件判断语句中,js有六种假值:false, null, undefined, '', NAN, 0。先来看几个例子:

[] === []
NaN === NaN
NaN == NaN
0 == []
'' == []
'' == {}
[] == undefined
{} == []
null == undefined

以上这些判断结果是什么,大家能否一看就知道结果呢?笔者以前对==和===都只有大概的印象,相信大家也都知道,== 判断如果两边变量的类型不同,会将其先做类型转换再作判断,而 === 则不做类型转换,如果类型不同,就一定返回 false。但是笔者最近看到了一个题目,感觉很有意思,贴出来给大家看看:

var x = 1;
var obj = {
  valueOf: function(){ 
    x = 2; 
    return 0 
    }
  }
console.log(obj == 0, x)

恩,这段代码输出的结果是 true, 2,是不是不可思议?还有~

var x = 1;
var obj = {
  valueOf: function(){ 
    return {} 
  }, 
  toString: function(){ 
    return {}
  }
 }
 console.log(obj == 0)

这段代码直接抛出了异常: Uncaught TypeError: Cannot convert object to primitive value。

如果你和我一样觉得很奇怪,那就继续往下看吧~

=== 的规则

这个比较简单,我把规则罗列一下

  1. 如果类型不同,就不相等
  2. 如果两个都是数值,并且是同一个值,那么相等,例外的是,如果其中至少一个是NaN,那么不相等。(判断一个值是否是 NaN,只能用isNaN() 来判断)
  3. 如果两个都是字符串,每个位置的字符都一样,那么相等;否则不相等。
  4. 如果两个值都是true,或者都是false,那么相等。
  5. 如果两个值都引用同一个对象或函数,那么相等;否则不相等。
  6. 如果两个值都是null,或者都是undefined,那么相等。

这里不难发现,复合类型的数据(比如对象、数组、函数等)之间的比较不是比较他们的值是否相等,而是比较他们引用的对象是否一样,因此也不难明白,为什么 [] === [] 判断为false了。

比如:

JavaScript中三个等号和两个等号你了解多少

== 探究

看下 == 的规则

  1. 如果两个值类型相同,进行 === 比较。
  2. 如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较:
  3. 如果一个是null、一个是undefined,那么相等。
  4. 如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。
  5. 如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。
  6. 如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。 js核心内置类,会尝试valueOf先于toString。例外的是Date,Date利用的是toString转换。非js核心的对象,会比较麻烦,有兴趣的同学可以研究一下
  7. 任何其他组合,都不相等。

看到这里,第六条,我们就可以明白,为什么上面的代码会输出意想不到的结果甚至抛出错误了。

再来看一题:

if (x == 10) 
  x += 5

根据上面的规则,试想一下,如果我们输入的x是字符串20,那么x的结果会变成什么样?没错,就是205,而往往这种情况我们的目的是想计算20+5的值。

综合上面的例子,不难看出,== 的比较看似会比较方便,比如 1 == '1' ,但是会埋下隐患,比如可能对类型做出错误的假设。因此大多数人建议我们少用== 而尽量使用 ===,事实上我也推荐如果明确知道类型,还是最好用===。

再举个简单的例子:团队协作中你肯定需要读别人的代码。而当你看到==时,要判断清楚作者的代码意图是确实需要转型,还是无所谓要不要转型只是随手写了,还是不应该转型但是写错了……所花费的脑力和时间比明确的===(加上可能需要的明确转型)要多得多。这样一想,===不要好太多。

明白了==的机制,那么判断这6个假值,就变得容易了。

简单看看几个例子,大家看看是真是假~

false == ''
false == []
0 == []
'' == []
[] == []
[] == {}
null == undefined
false == undefined

总结

可以用一张图来表达 == 返回true的几个假值:

JavaScript中三个等号和两个等号你了解多少

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

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

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

  1. 对方是对象,对象使用toString()或者valueOf()进行转换;
  2. 对方是数字,字符串转数字;
  3. 对方是字符串,直接比较;
  4. 其他返回false
  5. 如果是数字,对方是对象,对象取valueOf()或者toString()进行比较, 其他一律返回false
  6. null, undefined不会进行类型转换, 但它们俩相等

后记

我的建议是:如果你的的确确知道你在做什么(了解类型转换的结果),可以用==;否则还是用===吧。

在网上无意中看到的图,大家可以参考看看:

==号

JavaScript中三个等号和两个等号你了解多少

===号

JavaScript中三个等号和两个等号你了解多少

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery tools 系列 scrollable(2)
Sep 06 Javascript
js封装的textarea操作方法集合(兼容很好)
Nov 16 Javascript
读jQuery之三(构建选择器)
Jun 11 Javascript
zShowBox 图片放大展示jquery版 兼容性
Sep 24 Javascript
8款非常棒的响应式jQuery 幻灯片插件推荐
Feb 02 Javascript
javascript日期对象格式化为字符串的实现方法
Jan 14 Javascript
使用EVAL处理jqchart jquery 折线图返回数据无效的解决办法
Nov 26 Javascript
React Native中TabBarIOS的简单使用方法示例
Oct 13 Javascript
vue如何安装使用Quill富文本编辑器
Sep 21 Javascript
前端面试知识点目录一览
Apr 15 Javascript
Layui Table js 模拟选中checkbox的例子
Sep 03 Javascript
Nautil 中使用双向数据绑定的实现
Oct 02 Javascript
原生js实现简单的链式操作
Jul 04 #Javascript
详解用vue编写弹出框组件
Jul 04 #Javascript
使用vue构建一个上传图片表单
Jul 04 #Javascript
vue-resource 拦截器(interceptor)的使用详解
Jul 04 #Javascript
JavaScript在控件上添加倒计时功能的实现代码
Jul 04 #Javascript
JavaScript异步上传图片文件的实例代码
Jul 04 #Javascript
详解vue-router和vue-cli以及组件之间的传值
Jul 04 #Javascript
You might like
php.ini中的php-5.2.0配置指令详解
2008/03/27 PHP
thinkPHP交易详情查询功能详解
2016/12/02 PHP
laravel邮件发送的实现代码示例
2020/01/31 PHP
tp5框架基于Ajax实现列表无刷新排序功能示例
2020/02/10 PHP
javascript删除数组元素并且数组长度减小的简单实例
2014/02/14 Javascript
jquery 新建的元素事件绑定问题解决方案
2014/06/12 Javascript
jquery仅用6行代码实现滑动门效果
2015/09/07 Javascript
微信公众号 客服接口的开发实例详解
2016/09/28 Javascript
JS操作时间 - UNIX时间戳的简单介绍(必看篇)
2017/08/16 Javascript
vue.js删除列表中的一行
2018/06/30 Javascript
vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截)
2018/10/24 Javascript
javascript中数组的常用算法深入分析
2019/03/12 Javascript
JavaScript碎片—函数闭包(模拟面向对象)
2019/03/13 Javascript
微信小程序Flex布局用法深入浅出分析
2019/04/25 Javascript
vue ssr服务端渲染(小白解惑)
2019/11/10 Javascript
vue2.x 对象劫持的原理实现
2020/04/19 Javascript
微信小程序反编译的实现
2020/12/10 Javascript
[52:44]VGJ.T vs infamous Supermajor小组赛D组败者组第一轮 BO3 第一场 6.3
2018/06/04 DOTA
详解JavaScript编程中的window与window.screen对象
2015/10/26 Python
python实现数据库跨服务器迁移
2018/04/12 Python
Flask框架响应、调度方法和蓝图操作实例分析
2018/07/24 Python
python 日志模块 日志等级设置失效的解决方案
2020/05/26 Python
Keras—embedding嵌入层的用法详解
2020/06/10 Python
numpy中生成随机数的几种常用函数(小结)
2020/08/18 Python
html5实现canvas阴影效果示例
2014/05/07 HTML / CSS
诺心蛋糕官网:LE CAKE
2018/08/25 全球购物
迪卡侬波兰体育用品商店:Decathlon波兰
2020/03/31 全球购物
德国最大的婴儿用品网上商店:Kidsroom.de(支持中文)
2020/09/02 全球购物
英国哈罗德园艺:Harrod Horticultural
2020/03/31 全球购物
临床医学专业学生的自我评价分享
2013/11/21 职场文书
事业单位绩效考核实施方案
2014/03/27 职场文书
设备管理实施方案
2014/05/31 职场文书
副校长个人对照检查材料思想汇报
2014/10/04 职场文书
毕业生见习报告总结
2014/11/08 职场文书
国家助学金受助感言
2015/08/01 职场文书
pd.drop_duplicates删除重复行的方法实现
2022/06/16 Python