javascript中的相等操作符(==与===区别)


Posted in Javascript onDecember 21, 2019

1.前言

我们在编程的过程中,经常会遇到判断两个变量是否相等的情况,ECMAscript提供了两种相等操作符”==”和”===”来判断,这两种操作都会返回一个boolean值。一般来说,我们把”==”称之为相等,称”===”为全等。当两相比较的两个变量数据类型一致时,情况比较简单,而当操作符两边的变量类型不一致,甚至其中的某个变量是对象时,情况就比较复杂了,下面分别介绍当操作数类型不同时运算结果会怎么样。

2.全等操作符 “===”

全等操作符”===”的情况相对来说比较简单。当用全等操作符”===”来判断时,首先检查操作符两边操作数数据类型是否一致,若不一致,则直接返回false,否则,才进行下一步判断。如果是两个boolean的比较,则”===”两边必须同为true或同为false,才可以返回true,否则返回false.若两相比较的是数字,那么只有当这两个数字大小相等时才会返回true,否则返回false。如果要比较的两个变量是字符串,先比较两个字符串的长度length是否相等,如果长度不一样,则返回false,如果相等,则从两个变量的第一个字符开始比较是否相等,一直比较到最后一位,如果其中的某一位不想等,则返回false,否则返回true,(注意:字符串的比较是不会忽略空格的,所以在比较两个字符串是否相等时,为确保安全,应该先去除空格,然后把两个字符串同转为大写或者小写之后再进行比较)。而null只有在null===null的情况下才会返回true,其它情况都返回false,同样,undefined只有在undefined===undefined的情况下才会返回true,否则返回false。如:

true === 1    //false
"1" === 1    //false
 
//boolean的比较
true === true  //true
true === false  //false

//string的比较
"hello" === "helloworrld" //false
"hello" === "world" //false
"hello" === " hello" //false
"hello" === "hellO" //false
"hello" === "hello" //true

//number的比较
1 === 1  //true
1 === 1.0 //true
1 === 1.2 //false

//null和undefined的比较
undefined === undefined  //true
null === null       //true
undefined === null    //false,两者在"=="时才返回true

如果进行”===”比较的两个操作数不是基本类型值,而是两个对象,这时候判断依据就是,判断这两个变量是否是”同一个”对象

var a,b,c;
a = b = {
	name : '柳轻侯',
	city : '南京'
};
c = {
	name : '柳轻侯',
	city : '南京'
};
a === b   //true
a === c   //false

两个对象仅仅”长得一样”是不够的,a和c都是Object实例,且两者拥有相同的属性和值,可是这两个却不是”同一个”对象,因为实际上a和c指向了两个不同的实例,所以这两个对象是不全等的。而a和b却是指向了同一个对象,换个说法,a和b是同一个对象的不同别名,他们实际上指向的对象是完全相同的,所以a === b。”!==” 与 “===” 比较规则一样,在此不再赘述。

3.相等操作符”==”

全等操作符在进行判断的时候,如果两个变量的类型不同,则直接返回false,而与此不同,”==”相等操作符在判断的时候,如果两个变量的类型不同,则会做一个隐式的类型转换,把要比较的两个值转化为相同的类型再做比较,那么这种转化规则是怎么样的?

在转化不同数据类型时,相等和不等操作符遵循下面的基本规则

  • 如果其中一个操作数是是boolean值,则在比较之前会先将boolean值转化为number值,true转化为1,false转为0;
  • 如果其中一个操作数是string类型,而另一个是number类型,则在比较之前先将string类型转化为number类型再进行判断;
  • 在比较之前,undefined和null是不会转为其他值进行比较的;
  • 如果其中一个操作数是对象,而另一个是基本类型值,则在比较之前先将对象转为基本类型值,然后再依据前面的规则进行后续的比较;

两个操作数在比较时遵循下列规则

  • undefined和null是相等的,即:undefined == null;
  • 如果有一个操作数是NaN,那么返回false,即使两个操作数都是NaN,也会返回false;
  • 如果两个操作数是对象,则比较规则跟”===”的比较规则是一样的,除非这两个操作数是同一个对象,则返回true,否则返回false;

此处需要注意的是,NaN == NaN是返回false的,NaN意思是 not a number,也就是说该操作数是一个非数字,这个非数字是不确定的,它的值是未知的,甚至可能根本就不能用javascript的语法表示出来,这样一个未知量是不能用来进行特定比较的,两个未知的东西,如果不能确定它的值是什么,当然不能说 NaN == NaN。那么既然不能用”==”来比较,我们怎么去判定一个变量是不是NaN呢 ,既然不能用相等来判定,那么不妨反其道而行之,用”!=”来判定,判定一个变量是否不等于NaN。比如:

//如果需要判定一个变量是不是NaN,可以如下
//a是你需要判定的变量
if((typeof a === "number") && a != NaN ){  //此处需要注意,NaN也是number类型
	//TODO 
}

4.常见比较情况及其结果

null == undefined  // true 
"NaN" == NaN    // false 
5 == NaN      // false 
NaN == NaN     // false 
NaN != NaN     // true 
false == 0     // true 
true == 1      // true 
true == 2      // false 
undefined == 0   // false 
null == 0      // false
"5" == 5      // true

5.典型例题解析

![] == [] //true

这是一道比较容易令人困惑的题,按照正常的思维模式,对一个操作数逻辑取反,跟这个操作数本身的值是相对的,如果这个操作数本身的值是true,那么取反之后就是false,反之,如果这个操作数的值是false,那么对其逻辑取反之后就是true,无论如何也不会是同一个值,可是事实上却是![] == []。首先,![]的值是false,因为这里[]被当成了一个数组的实例,是一个对象,而对象都是真值,对其取反,得到一个假值,也就是false。其次看等号右边,[]是一个对象,要将其转为基本类型值,会先调用数组的valueOf方法,而数组的valueOf方法返回数组本身,没有得到一个基本值,这时候要继续调用数组的toString方法,得到一个””空字符串,所以这时候也就变成了false == “”是否为真的问题了,而根据前面的规则,如果有一个操作数为boolean值,会将其转为数值,false转化为0。进而,问题转化为0 == “”是否为真值的问题,当number和string比较时,会将string转为number,而””会转为0。最后,问题变演化成了0 == 0是否为真值,毋庸置疑,结果是true。这里要注意的就是![],它被当成了一个整体的逻辑值,是直接对对象进行取反,是一个假值,而不是先把[]转化为基本值再取反

6.小结

“==”在比较不同类型值得时候会进行隐式的类型转化,而”===”不会转化,全等一定相等,相等却不一定全等,这是一个充分不必要条件。undefined和null相等而不全等,且在相等比较的时候不会转化为其他类型的值。NaN是不等于NaN 的,要判断某个变量是不是NaN,要用”!=”。对象和非对象在进行比较的时候会先转为基本类型值然后再根据上面的规则进行比较。

7.参考资料

《javascript高级程序设计》
《javascript权威指南》

Javascript 相关文章推荐
jquery将一个表单序列化为一个对象的方法
Dec 02 Javascript
javascript中的括号()用法小结
Apr 14 Javascript
js仿苹果iwatch外观的计时器代码分享
Aug 26 Javascript
jquery表单验证需要做些什么
Nov 17 Javascript
js时间戳转为日期格式的方法
Dec 28 Javascript
jQuery实现输入框邮箱内容自动补全与上下翻动显示效果【附demo源码下载】
Sep 20 Javascript
在页面中引入js的两种方法(推荐)
Aug 29 Javascript
javascript 中事件冒泡和事件捕获机制的详解
Sep 01 Javascript
微信小程序获取手机网络状态的方法【附源码下载】
Dec 08 Javascript
Node.js JSON模块用法实例分析
Jan 04 Javascript
vue项目配置使用flow类型检查的步骤
Mar 18 Javascript
Vue中插槽slot的使用方法与应用场景详析
Jun 08 Vue.js
JavaScript中的相等操作符使用详解
Dec 21 #Javascript
高性能js数组去重(12种方法,史上最全)
Dec 21 #Javascript
ES6常用小技巧总结【去重、交换、合并、反转、迭代、计算等】
Dec 21 #Javascript
vue中根据时间戳判断对应的时间(今天 昨天 前天)
Dec 20 #Javascript
angularjs模态框的使用代码实例
Dec 20 #Javascript
推荐几个不错的console调试技巧实现
Dec 20 #Javascript
Vue+Node服务器查询Mongo数据库及页面数据传递操作实例分析
Dec 20 #Javascript
You might like
Wordpress php 分页代码
2009/10/21 PHP
php实现的短网址算法分享
2014/06/20 PHP
PHP简单获取视频预览图的方法
2015/03/12 PHP
新浪微博OAuth认证和储存的主要过程详解
2015/03/27 PHP
javascript 构建一个xmlhttp对象池合理创建和使用xmlhttp对象
2010/01/15 Javascript
Firefox中beforeunload事件的实现缺陷浅析
2012/05/03 Javascript
一个简单的jquery的多选下拉框(自写)
2014/05/05 Javascript
影响jQuery使用的14个方面
2014/09/01 Javascript
简单分析javascript面向对象与原型
2015/05/21 Javascript
Jquery基础之事件操作详解
2016/06/14 Javascript
JQuery组件基于Bootstrap的DropDownList(完整版)
2016/07/05 Javascript
HTML5基于Tomcat 7.0实现WebSocket连接并实现简单的实时聊天
2016/10/31 Javascript
Easyui Tree获取当前选择节点的所有顶级父节点
2017/02/14 Javascript
前端把html表格生成为excel表格的实例
2017/09/19 Javascript
Node.js微信 access_token ( jsapi_ticket ) 存取与刷新的示例
2017/09/30 Javascript
微信小程序loading组件显示载入动画用法示例【附源码下载】
2017/12/09 Javascript
ionic3实战教程之随机布局瀑布流的实现方法
2017/12/28 Javascript
基于Vue渲染与插件的加载顺序的问题详解
2018/03/05 Javascript
使用typescript改造koa开发框架的实现
2020/02/04 Javascript
vue props 一次传多个值实例
2020/07/22 Javascript
[01:24:09]Ti4 冒泡赛第二轮DK vs C9 1
2014/07/14 DOTA
python处理图片之PIL模块简单使用方法
2015/05/11 Python
Python编程实现微信企业号文本消息推送功能示例
2017/08/21 Python
Django项目之Elasticsearch搜索引擎的实例
2019/08/21 Python
opencv中图像叠加/图像融合/按位操作的实现
2020/04/01 Python
python numpy实现rolling滚动案例
2020/06/08 Python
Python实现SMTP邮件发送
2020/06/16 Python
Python图像处理二值化方法实例汇总
2020/07/24 Python
台湾三立电视电商平台:电电购
2019/09/09 全球购物
美国婴儿和儿童服装购物网站:PatPat
2020/10/01 全球购物
爱心倡议书范文
2014/05/12 职场文书
公司采购主管岗位职责
2014/06/17 职场文书
2015年妇联工作总结范文
2015/04/22 职场文书
信用卡收入证明范本
2015/06/12 职场文书
CSS3实现的侧滑菜单
2021/04/27 HTML / CSS
Python序列化与反序列化相关知识总结
2021/06/08 Python