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 相关文章推荐
利用div+jquery自定义滚动条样式的2种方法
Jul 18 Javascript
jquery插件tooltipv顶部淡入淡出效果使用示例
Dec 05 Javascript
node.js中的favicon.ico请求问题处理
Dec 15 Javascript
jQuery中scrollLeft()方法用法实例
Jan 16 Javascript
jQuery实现的产品自动360度旋转展示特效源码分享
Aug 21 Javascript
jQuery表单验证功能实例
Aug 28 Javascript
给before和after伪元素设置js效果的方法
Dec 04 Javascript
Vue.js实现的计算器功能完整示例
Jul 11 Javascript
jquery图片预览插件实现方法详解
Jul 18 jQuery
Vue封装的组件全局注册并引用
Jul 24 Javascript
微信小程序实现音乐播放页面布局
Dec 11 Javascript
react 路由Link配置详解
Nov 11 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
第二节 对象模型 [2]
2006/10/09 PHP
攻克CakePHP系列一 连接MySQL数据库
2008/10/22 PHP
php 什么是PEAR?
2009/03/19 PHP
PHP利用header跳转失效的解决方法
2014/10/24 PHP
PHP框架Laravel学习心得体会
2015/10/28 PHP
简单实用的PHP文本缓存类实例
2019/03/22 PHP
msn上的tab功能Firefox对childNodes处理的一个BUG
2008/01/21 Javascript
JS中不为人知的五种声明Number的方式简要概述
2013/02/22 Javascript
javascript中的作用域和上下文使用简要概述
2013/12/05 Javascript
JavaScript检查某个function是否是原生代码的方法
2014/08/20 Javascript
js使用split函数按照多个字符对字符串进行分割的方法
2015/03/20 Javascript
Javascript BOM学习小结(六)
2015/11/26 Javascript
JS实现响应鼠标点击动画渐变弹出层效果代码
2016/03/25 Javascript
jQuery轮播图效果精简版完整示例
2016/09/04 Javascript
JS小数转换为整数的方法分析
2017/01/07 Javascript
JavaScript获取URL参数的方法之一
2017/03/24 Javascript
小程序图片剪裁加旋转的示例代码
2018/07/10 Javascript
基于Nodejs的Tcp封包和解包的理解
2018/09/19 NodeJs
小白教程|一小时上手最流行的前端框架vue(推荐)
2019/04/10 Javascript
weui上传多图片,压缩,base64编码的示例代码
2020/06/22 Javascript
HTML元素拖拽功能实现的完整实例
2020/12/04 Javascript
无法使用pip命令安装python第三方库的原因及解决方法
2018/06/12 Python
Python实用技巧之利用元组代替字典并为元组元素命名
2018/07/11 Python
Python实现监控键盘鼠标操作示例【基于pyHook与pythoncom模块】
2018/09/04 Python
Django实现微信小程序的登录验证功能并维护登录态
2019/07/04 Python
Python基于smtplib协议实现发送邮件
2020/06/03 Python
使用pygame实现垃圾分类小游戏功能(已获校级二等奖)
2020/07/23 Python
css3图片边框border-image的用法
2017/06/30 HTML / CSS
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
初三开学计划书
2014/04/27 职场文书
小学教师培训方案
2014/06/09 职场文书
单方离婚协议书范本2014
2014/10/28 职场文书
2015年高三毕业班班主任工作总结
2015/10/22 职场文书
教你如何使用Python实现二叉树结构及三种遍历
2021/06/18 Python
PHP设计模式(观察者模式)
2021/07/07 PHP
SQL中的连接查询详解
2022/06/21 SQL Server