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 相关文章推荐
发一个自己用JS写的实用看图工具实现代码
Jul 26 Javascript
Javascript load Page,load css,load js实现代码
Mar 31 Javascript
Ext JS添加子组件的误区探讨
Jun 28 Javascript
Table冻结表头示例代码
Aug 20 Javascript
js实现tab切换效果实例
Sep 16 Javascript
javascript创建含数字字母的随机字符串方法总结
Aug 01 Javascript
js style.display=block显示布局错乱问题的解决方法
Sep 21 Javascript
微信小程序实现跑马灯效果完整代码(附效果图)
May 30 Javascript
JavaScript折半查找(二分查找)算法原理与实现方法示例
Aug 06 Javascript
vue 双向数据绑定的实现学习之监听器的实现方法
Nov 30 Javascript
vue-router源码之history类的浅析
May 21 Javascript
layer弹出层扩展主题的方法
Sep 11 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
用文本文件制作留言板提示(下)
2006/10/09 PHP
php防止SQL注入详解及防范
2013/11/12 PHP
PHP定时执行任务实现方法详解(Timer)
2015/07/30 PHP
最准确的php截取字符串长度函数
2015/10/29 PHP
Yii框架实现邮箱激活的方法【数字签名】
2016/10/18 PHP
PHP设计模式之原型设计模式原理与用法分析
2018/04/25 PHP
js bind 函数 使用闭包保存执行上下文
2011/12/26 Javascript
前台js对象在后台转化java对象的问题探讨
2013/12/20 Javascript
jquery单选框radio绑定click事件实现方法
2015/01/14 Javascript
JS实现很实用的对联广告代码(可自适应高度)
2015/09/18 Javascript
基于JavaScript实现动态添加删除表格的行
2016/02/01 Javascript
清除浏览器缓存的几种方法总结(必看)
2016/12/09 Javascript
jquery 仿锚点跳转到页面指定位置的实例
2017/02/14 Javascript
js+html5实现复制文字按钮
2017/07/15 Javascript
微信小程序实现倒计时调用相机自动拍照功能
2018/06/10 Javascript
微信小程序实现多行文字超出部分省略号显示功能
2019/10/23 Javascript
vue限制输入框只能输入8位整数和2位小数的代码
2019/11/06 Javascript
python实现划词翻译
2020/04/23 Python
python实现根据主机名字获得所有ip地址的方法
2015/06/28 Python
Python3.4学习笔记之列表、数组操作示例
2019/03/01 Python
Python 中Django安装和使用教程详解
2019/07/03 Python
Tensorflow 模型转换 .pb convert to .lite实例
2020/02/12 Python
在 Python 中使用 MQTT的方法
2020/08/18 Python
python 如何对logging日志封装
2020/12/02 Python
CSS3实现同时执行倾斜和旋转的动画效果
2016/10/27 HTML / CSS
蹦床仓库:Trampoline Warehouse
2018/12/06 全球购物
extern是什么意思
2016/03/10 面试题
Linux如何命名文件--使用文件名时应注意
2014/05/29 面试题
高职教师岗位职责
2013/12/24 职场文书
校园活动策划书范文
2014/01/10 职场文书
争论的故事教学反思
2014/02/06 职场文书
聚美优品恶搞广告词
2014/03/14 职场文书
高考标语大全
2014/06/05 职场文书
工程部经理岗位职责
2015/02/02 职场文书
2016年大学迎新晚会工作总结
2015/10/15 职场文书
win10电脑右下角输入法图标不见了?Win10右下角不显示输入法的解决方法
2022/07/23 数码科技