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 获取对象的几种方式介绍
Jan 17 Javascript
javaScript中with函数用法实例分析
Jun 08 Javascript
js模拟淘宝网的多级选择菜单实现方法
Aug 18 Javascript
Jquery ajax 同步阻塞引起的UI线程阻塞问题
Nov 17 Javascript
基于Jquery插件实现跨域异步上传文件功能
Apr 26 Javascript
详解vue2.0+vue-video-player实现hls播放全过程
Mar 02 Javascript
微信小程序使用二次贝塞尔曲线画波浪
Dec 25 Javascript
a标签调用js的方法总结
Sep 05 Javascript
uploadify插件实现多个图片上传并预览
Sep 30 Javascript
微信小程序获取复选框全选反选选中的值(实例代码)
Dec 17 Javascript
vue 路由懒加载中给 Webpack Chunks 命名的方法
Apr 24 Javascript
Vue文本模糊匹配功能如何实现
Jul 30 Javascript
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
PHP中的日期处理方法集锦
2007/01/02 PHP
一个捕获函数输出的函数
2007/02/14 PHP
php数字转汉字代码(算法)
2011/10/08 PHP
Yii净化器CHtmlPurifier用法示例(过滤不良代码)
2016/07/15 PHP
php实现映射操作实例详解
2019/10/02 PHP
javascript loadScript异步加载脚本示例讲解
2013/11/14 Javascript
Ajax提交与传统表单提交的区别说明
2014/02/07 Javascript
node.js实现BigPipe详解
2014/12/05 Javascript
JS实现简单的二维矩阵乘积运算
2016/01/26 Javascript
Angular.Js的自动化测试详解
2016/12/09 Javascript
jQuery插件zTree实现删除树节点的方法示例
2017/03/08 Javascript
jQuery插件FusionCharts绘制的3D环饼图效果示例【附demo源码】
2017/04/02 jQuery
详解用webpack2.0构建vue2.0超详细精简版
2017/04/05 Javascript
vue绑定的点击事件阻止冒泡的实例
2018/02/08 Javascript
Vue-cli@3.0 插件系统简析
2018/09/05 Javascript
BootStrap中的模态框(modal,弹出层)功能示例代码
2018/11/02 Javascript
小程序实现单选多选功能
2018/11/04 Javascript
jQuery-ui插件sortable实现自由拖动排序
2018/12/01 jQuery
layui 表单标签的校验方法
2019/09/04 Javascript
javascript实现倒计时提示框
2021/03/02 Javascript
python基础教程之Filter使用方法
2017/01/17 Python
R vs. Python 数据分析中谁与争锋?
2017/10/18 Python
使用Python实现企业微信的自动打卡功能
2019/04/30 Python
python处理大日志文件
2019/07/23 Python
Python实现图片识别加翻译功能
2019/12/26 Python
日本PLST在线商店:日本时尚杂志刊载的人气服装
2016/12/10 全球购物
eBay美国官网:eBay.com
2020/10/24 全球购物
会计专业自荐信范文
2013/12/02 职场文书
视光学毕业生自荐书范文
2014/02/13 职场文书
2014两会优秀的心得体会范文
2014/03/17 职场文书
好听的队名和口号
2014/06/09 职场文书
2014年党员学习“三严三实”思想汇报
2014/09/15 职场文书
白鹤梁导游词
2015/02/06 职场文书
2016猴年春节问候语
2015/11/11 职场文书
导游词之西江千户苗寨
2019/12/24 职场文书
pytorch Dropout过拟合的操作
2021/05/27 Python