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 相关文章推荐
多引号嵌套的变量命名的问题
May 09 Javascript
浅析Node在构建超媒体API中的作用
Jul 30 Javascript
jQuery使用之标记元素属性用法实例
Jan 19 Javascript
javaScript基础语法介绍
Feb 28 Javascript
JS在onclientclick里如何控制onclick的执行
May 30 Javascript
bootstrap滚动监控器使用方法解析
Jan 13 Javascript
使用JavaScript判断用户输入的是否为正整数(两种方法)
Feb 05 Javascript
微信小程序 setData的使用方法详解
Apr 20 Javascript
解决canvas画布使用fillRect()时高度出现双倍效果的问题
Aug 03 Javascript
微信小程序实现聊天对话(文本、图片)功能
Jul 06 Javascript
详解Vue的钩子函数(路由导航守卫、keep-alive、生命周期钩子)
Jul 24 Javascript
在vue中阻止浏览器后退的实例
Nov 06 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
PHP Curl多线程原理实例详解
2013/11/06 PHP
php操作MongoDB类实例
2015/06/17 PHP
PHP实现的曲线统计图表示例
2016/11/10 PHP
PHP调用API接口实现天气查询功能的示例
2017/09/21 PHP
PHP goto语句用法实例
2019/08/06 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
纯js实现瀑布流展现照片(自动适应窗口大小)
2013/04/08 Javascript
浅析showModalDialog数据缓存问题(用禁止浏览器缓存解决)
2013/07/09 Javascript
浅析js预加载/延迟加载
2014/09/25 Javascript
使用jspdf生成pdf报表
2015/07/03 Javascript
基于jquery实现的树形菜单效果代码
2015/09/06 Javascript
分享几种比较简单实用的JavaScript tabel切换
2015/12/31 Javascript
Bootstrap选项卡与Masonry插件的完美结合
2016/07/06 Javascript
基于百度地图实现产品销售的单位位置查看功能设计与实现
2016/10/21 Javascript
使用JS读取XML文件的方法
2016/11/25 Javascript
JavaScript数据结构之数组的表示方法示例
2017/04/12 Javascript
Angular实现的进度条功能示例
2018/02/18 Javascript
基于Vue实现微信小程序的图文编辑器
2018/07/25 Javascript
详解vue服务端渲染浏览器端缓存(keep-alive)
2018/10/12 Javascript
Vue v-text指令简单使用方法示例
2019/09/19 Javascript
Vue实现导航栏菜单
2020/08/19 Javascript
解决vue中使用less/sass及使用中遇到无效的问题
2020/10/24 Javascript
Python守护进程和脚本单例运行详解
2017/01/06 Python
在Python dataframe中出生日期转化为年龄的实现方法
2018/10/20 Python
python实现websocket的客户端压力测试
2019/06/25 Python
HTML5 Blob 实现文件下载功能的示例代码
2019/11/29 HTML / CSS
私有程序集与共享程序集有什么区别
2013/04/05 面试题
人事主管岗位职责
2014/01/30 职场文书
校园之声广播稿
2014/01/31 职场文书
感恩小明星事迹材料
2014/05/23 职场文书
安全目标责任书
2014/07/22 职场文书
事业单位岗位说明书
2015/10/08 职场文书
入伍志愿书怎么写?
2019/07/19 职场文书
sqlserver2017共享功能目录路径不可改的解决方法
2021/04/16 SQL Server
Python实现生活常识解答机器人
2021/06/28 Python
游戏《东方异文石:爱亚利亚黎明》正式版发布
2022/04/03 其他游戏