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 相关文章推荐
js实现的跟随鼠标移动的时钟效果(中英文日期显示)
Jan 17 Javascript
JavaScript中使用typeof运算符需要注意的几个坑
Nov 08 Javascript
简介JavaScript中search()方法的使用
Jun 06 Javascript
浅谈Javascript数组索引
Jul 29 Javascript
jQuery滚动加载图片实现原理
Dec 14 Javascript
js滑动提示效果代码分享
Mar 10 Javascript
使用jquery.qrcode.min.js实现中文转化二维码
Mar 11 Javascript
jquery基本选择器匹配多个元素的实现方法
Sep 05 Javascript
如何在vue中使用ts的示例代码
Feb 28 Javascript
vue实现全屏滚动效果(非fullpage.js)
Mar 07 Javascript
纯js+css实现在线时钟
Aug 18 Javascript
Vue.js暴露方法给WebView的使用操作
Sep 07 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
node使用request请求的方法
Dec 20 #Javascript
You might like
剧场版动画《PSYCHO-PASS 3 FIRST INSPECTOR》3月27日日本上映!
2020/03/06 日漫
php $_ENV为空的原因分析
2009/06/01 PHP
php 提速工具eAccelerator 配置参数详解
2010/05/16 PHP
php去除重复字的实现代码
2011/09/16 PHP
PHP大批量插入数据库的3种方法和速度对比
2014/07/08 PHP
PHP MVC框架skymvc支持多文件上传
2016/05/26 PHP
使用PHP访问RabbitMQ消息队列的方法示例
2018/06/06 PHP
PHP中使用CURL发送get/post请求上传图片批处理功能
2018/10/15 PHP
Laravel 5.5 实现禁用用户注册示例
2019/10/24 PHP
浅析document.createDocumentFragment()与js效率
2013/07/08 Javascript
js 实现的可折叠留言板(附源码下载)
2014/07/01 Javascript
JQuery实现样式设置、追加、移除与切换的方法
2015/06/11 Javascript
JS实现可展开折叠层的鼠标拖曳效果
2015/10/09 Javascript
JavaScript实现图片自动加载的瀑布流效果
2016/04/11 Javascript
微信小程序左右滑动切换页面详解及实例代码
2017/02/28 Javascript
微信小程序使用map组件实现路线规划功能示例
2019/01/22 Javascript
JavaScript如何操作css
2020/10/24 Javascript
5种Python单例模式的实现方式
2016/01/14 Python
请不要重复犯我在学习Python和Linux系统上的错误
2016/12/12 Python
python中Switch/Case实现的示例代码
2017/11/09 Python
对python创建及引用动态变量名的示例讲解
2018/11/10 Python
Python基于scipy实现信号滤波功能
2019/05/08 Python
对Python中小整数对象池和大整数对象池的使用详解
2019/07/09 Python
opencv resize图片为正方形尺寸的实现方法
2019/12/26 Python
Django用户登录与注册系统的实现示例
2020/06/03 Python
Carolina工作鞋官网:Carolina Footwear
2019/03/14 全球购物
意大利辅助药品、药物和补品在线销售:FarmaEurope
2020/04/29 全球购物
自荐信格式的六要素
2013/09/21 职场文书
师生聚会感言
2014/01/26 职场文书
销售内勤岗位职责
2014/04/15 职场文书
导师评语大全
2014/04/26 职场文书
安全生产目标管理责任书
2014/07/25 职场文书
捐款感谢信
2015/01/20 职场文书
2015年度物业公司工作总结
2015/04/27 职场文书
2015年医院科室工作总结范文
2015/05/26 职场文书
Golang 对es的操作实例
2022/04/20 Golang