JavaScript中的相等操作符使用详解


Posted in Javascript onDecember 21, 2019

ECMAScript 中的相等操作符由两个等于号 ( == ) 表示,如果两个操作数相等,则返回 true。

相等操作符会先转换操作数(通常称为强制转型),然后比较它们的相等性。

在转换不同的数据类型时,相等操作符遵循下列基本规则:

1. 如果有一个操作数是布尔值,则在比较相等性之前,将其转换为数值;

2. 如果一个操作数是字符串,另一个操作数是数值,在比较之前先将字符串转换为数值;

3. 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf() 方法,用得到的基本类型值按照前面的规则进行比较;

4. 如果有一个操作数是 NaN,无论另一个操作数是什么,相等操作符都返回 false;

5. 如果两个操作数都是对象,则比较它们是不是同一个对象。如果指向同一个对象,则相等操作符返回 true;

6. 在比较相等性之前,不能将 null 和 undefined 转成其他值。

7. null 和 undefined 是相等的。

以上内容摘自《 JavaScript 高级程序设计(第3版)》3.5.7

一、基本规则

上面阐述的 1、2、3 三条规则,总结成一句话就是:

如果相等操作符两边的操作数,不包含 null 或者 undefined,且两个操作数不全是对象,

在执行相等比较之前,会先调用 Number() 将两个操作数强制转为 Number 类型,然后进行比较

所以在使用相等操作符的时候,会有以下情况:

'55' == 55; //true
false == 0; //true
"wise" == 3; //false ( Number("wise") -> NaN )
[] == 0; //true ( Number([]) -> 0 )

但是在特殊情况下,也就是两边都有对象的时候,会产生看似不合理的结果:

NaN == NaN; //false (参考第4条规则)
[] == []; //false
[] == ![]; //true
{} == {}; //false
{} == !{}; //false

二、[] == [] 和 {} == {}

在 JavaScript 中,Object、Array、Function、RegExp、Date 都是引用类型

声明引用类型的时候,变量名保存在 js 的栈内存里面,而对应的值保存在堆内存里面

而这个变量在栈内存中实际保存的是:这个值在堆内存中的地址,也就是指针

var a = {};
var b = {};

上面的代码中,声明变量 a 的时候,在堆内存中存储了一个 Object,而 a 实际保存的这个 Object 的地址

然后声明变量 b 的时候,又存储了一个新的 Object

虽然 a 和 b 都保存了一个 Object,但这是两个独立的 Object,它们的地址是不同的

再结合前面的第5条规则:如果两个对象指向同一个对象,相等操作符返回 true

所以 {} == {} 的结果是 false,同样的, [] == [] 的结果也是 false

var c = b;
b == c; //true(变量c保存的是b的指针,它们指向同一个对象)

三、[] == ![] 和 {} == !{}

参考链接:JavaScript 运算符优先级

ECMAScript 中规定,逻辑非 (!) 的优先级高于相等操作符 ( == )

在比较 [] == ![] 的时候,先计算 ![] 得到布尔值 false

所以实际上比较的是 [] == false

然后根据上面的第1条规则和第3条规则,将两个操作数转为数值类型:

Number([]) == Number(false); // -> 0 == 0 -> true

在比较 {} == !{} 的时候,也是遵守同样的规则:

{} == !{} -> {} == false -> Number({}) == Number(false) -> NaN == 0

然后第4条规则规定:如果有一个操作数是 NaN,相等操作符返回 false

所以 {} == !{} 的结果是 false

小结:

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

Javascript 相关文章推荐
菜鸟javascript基础资料整理2
Dec 06 Javascript
对jQuery的事件绑定的一些思考(补充)
Apr 20 Javascript
用示例说明filter()与find()的用法以及children()与find()的区别分析
Apr 26 Javascript
JS中的prototype与面向对象的实例讲解
May 22 Javascript
js实现通用的微信分享组件示例
Mar 10 Javascript
EasyUi中的Combogrid 实现分页和动态搜索远程数据
Apr 01 Javascript
JavaScript对象数组如何按指定属性和排序方向进行排序
Jun 15 Javascript
JavaScript中的编码和解码函数
Feb 15 Javascript
js中DOM三级列表(代码分享)
Mar 20 Javascript
基于bootstrap按钮式下拉菜单组件的搜索建议插件
Mar 25 Javascript
利用Node.js了解与测量HTTP所花费的时间详解
Sep 22 Javascript
ajax jquery实现页面某一个div的刷新效果
Mar 04 jQuery
高性能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
node使用request请求的方法
Dec 20 #Javascript
You might like
用php的ob_start来生成静态页面的方法分析
2011/03/09 PHP
PHP 计算代码执行耗时的代码修正网上普遍错误
2011/05/14 PHP
腾讯微博提示missing parameter errorcode 102 错误的解决方法
2014/12/22 PHP
PHP下使用mysqli的函数连接mysql出现warning: mysqli::real_connect(): (hy000/1040): ...
2016/02/14 PHP
IE iframe的onload方法分析小结
2010/01/07 Javascript
基于jQuery的试卷自动排版系统实现代码
2011/01/06 Javascript
jQuery1.3.2 升级到jQuery1.4.4需要修改的地方
2011/01/06 Javascript
A标签中通过href和onclick传递的this对象实现思路
2013/04/19 Javascript
JavaScript ParseFloat()方法
2015/12/18 Javascript
JQuery插件Marquee.js实现无缝滚动效果
2016/04/26 Javascript
微信小程序 scroll-view组件实现列表页实例代码
2016/12/14 Javascript
js实现数组去重方法及效率?Ρ? target=
2017/02/14 Javascript
JS控件bootstrap datepicker使用方法详解
2017/03/25 Javascript
详解从新建vue项目到引入组件Element的方法
2017/08/29 Javascript
解决mpvue + vuex 开发微信小程序vuex辅助函数mapState、mapGetters不可用问题
2018/08/03 Javascript
vuex存值与取值的实例
2019/11/06 Javascript
JS实现电脑虚拟键盘的操作
2020/06/24 Javascript
python制作花瓣网美女图片爬虫
2015/10/28 Python
在Python中移动目录结构的方法
2016/01/31 Python
python使用turtle库与random库绘制雪花
2018/06/22 Python
python将字符串转变成dict格式的实现
2019/11/18 Python
在keras中获取某一层上的feature map实例
2020/01/24 Python
Python判断远程服务器上Excel文件是否被人打开的方法
2020/07/13 Python
Python实现http接口自动化测试的示例代码
2020/10/09 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的代码
2020/11/30 HTML / CSS
中国第一家杂志折扣订阅网:杂志铺
2016/08/30 全球购物
同步和异步有何异同,在什么情况下分别使用他们?
2012/12/28 面试题
幼儿运动会邀请函
2014/01/17 职场文书
烹调加工管理制度
2014/02/04 职场文书
教师开学感言
2014/02/14 职场文书
师德师风个人反思
2014/04/28 职场文书
简易离婚协议书(范本)
2014/10/25 职场文书
大学生求职自荐信
2015/03/24 职场文书
开网店计划分析
2019/07/30 职场文书
利用JavaScript写一个简单计算器
2021/11/27 Javascript
python数字图像处理数据类型及颜色空间转换
2022/06/28 Python