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 相关文章推荐
Firefox getBoxObjectFor getBoundingClientRect联系
Oct 26 Javascript
jQuery之排序组件的深入解析
Jun 19 Javascript
vue 使用eventBus实现同级组件的通讯
Mar 02 Javascript
vue-cli 引入、配置axios的方法
May 08 Javascript
vee-validate vue 2.0自定义表单验证的实例
Aug 28 Javascript
微信小程序车牌号码模拟键盘输入功能的实现代码
Nov 11 Javascript
详解如何在Angular优雅编写HTTP请求
Dec 05 Javascript
详解微信小程序支付流程与梳理
Jul 16 Javascript
vue 遮罩层阻止默认滚动事件操作
Jul 28 Javascript
vue 路由缓存 路由嵌套 路由守卫 监听物理返回操作
Aug 06 Javascript
js实现简单的无缝轮播效果
Sep 05 Javascript
Moment的feature导致线上bug解决分析
Sep 23 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
PHPWind与Discuz截取字符函数substrs与cutstr性能比较
2011/12/05 PHP
如何使用php输出时间格式
2013/08/31 PHP
ThinkPHP分页类使用详解
2014/03/05 PHP
PHP错误WARNING: SESSION_START() [FUNCTION.SESSION-START]解决方法
2014/05/04 PHP
codeigniter上传图片不能正确识别图片类型问题解决方法
2014/07/25 PHP
详解PHP的Yii框架中的Controller控制器
2016/03/29 PHP
jQuery对象和DOM对象使用说明
2010/06/25 Javascript
仿中关村在线首页弹出式广告插件(jQuery版)
2012/05/03 Javascript
jQuery实现的导航条切换可显示隐藏
2014/10/22 Javascript
JavaScript中window.showModalDialog()用法详解
2014/12/18 Javascript
Javascript核心读书有感之词法结构
2015/02/01 Javascript
JavaScript仿商城实现图片广告轮播实例代码
2016/02/06 Javascript
逻辑表达式中与或非的用法详解
2016/06/06 Javascript
Bootstrap中datetimepicker使用小结
2016/12/28 Javascript
vue将毫秒数转化为正常日期格式的实例
2018/09/16 Javascript
vue-quill-editor富文本编辑器简单使用方法
2018/09/21 Javascript
Windows下支持自动更新的Electron应用脚手架的方法
2018/12/24 Javascript
layer.open回调获取弹出层参数的实现方法
2019/09/10 Javascript
通过实例了解Javascript柯里化流程
2020/03/03 Javascript
学习python的几条建议分享
2013/02/10 Python
Python的CGIHTTPServer交互实现详解
2018/02/08 Python
Python实现程序判断季节的代码示例
2019/01/28 Python
详解Python 切片语法
2019/06/10 Python
浅析pip安装第三方库及pycharm中导入第三方库的问题
2020/03/10 Python
python3跳出一个循环的实例操作
2020/08/18 Python
python中random.randint和random.randrange的区别详解
2020/09/20 Python
Python fileinput模块如何逐行读取多个文件
2020/10/05 Python
南非最大的花卉和送礼服务:NetFlorist
2017/09/13 全球购物
建筑个人求职信范文
2014/01/25 职场文书
环保建议书200字
2014/05/14 职场文书
家装电话营销开场白
2015/05/29 职场文书
2019个人工作总结
2019/06/21 职场文书
创业计划书之韩国烧烤店
2019/09/19 职场文书
MySQL 全文检索的使用示例
2021/06/07 MySQL
spring boot项目application.properties文件存放及使用介绍
2021/06/30 Java/Android
在Windows Server 2012上安装 .NET Framework 3.5 所遇到的问题
2022/04/29 Servers