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 不支持 document.all的方法
Mar 12 Javascript
javascript 自动转到命名锚记
Jan 10 Javascript
jquery中实现标签切换效果的代码
Mar 01 Javascript
最短的IE判断代码
Mar 13 Javascript
js禁止页面复制功能禁用页面右键菜单示例代码
Aug 29 Javascript
js游戏人物上下左右跑步效果代码分享
Aug 28 Javascript
关于Javascript回调函数的一个妙用
Aug 29 Javascript
基于javascript实现按圆形排列DIV元素(一)
Dec 02 Javascript
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
Dec 14 Javascript
Node.js通过身份证号验证年龄、出生日期与性别方法示例
Mar 09 Javascript
Vue.js实战之组件之间的数据传递
Apr 01 Javascript
Node快速切换版本、版本回退(降级)、版本更新(升级)
Jan 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
造就帕卡马拉的帕卡斯是怎么被发现的
2021/03/03 咖啡文化
PHP开发文件系统实例讲解
2006/10/09 PHP
php 设计模式之 工厂模式
2008/12/19 PHP
Smarty foreach控制循环次数的实现详解
2013/07/03 PHP
PHP 正则判断中文UTF-8或GBK的思路及具体实现
2013/11/26 PHP
WordPress中编写自定义存储字段的相关PHP函数解析
2015/12/25 PHP
如何解决PHP使用mysql_query查询超大结果集超内存问题
2016/03/14 PHP
PHP Web表单生成器案例分析
2020/06/02 PHP
浅谈javascript 函数属性和方法
2015/01/21 Javascript
js同源策略详解
2015/05/21 Javascript
c#程序员对TypeScript的认识过程
2015/06/19 Javascript
Easyui form combobox省市区三级联动
2016/01/13 Javascript
jQuery.deferred对象使用详解
2016/03/18 Javascript
理解javascript对象继承
2016/04/17 Javascript
无法获取隐藏元素宽度和高度的解决方案
2017/03/07 Javascript
webpack实现热更新(实施同步刷新)
2017/07/28 Javascript
vue.js整合vux中的上拉加载下拉刷新实例教程
2018/01/09 Javascript
JS判断两个数组或对象是否相同的方法示例
2019/02/28 Javascript
微信小程序自定义胶囊样式
2020/12/27 Javascript
[01:11:37]完美世界DOTA2联赛PWL S2 SZ vs FTD.C 第一场 11.19
2020/11/19 DOTA
对python3 urllib包与http包的使用详解
2018/05/10 Python
Python实现读取txt文件并转换为excel的方法示例
2018/05/17 Python
PyQt5 多窗口连接实例
2019/06/19 Python
浅谈Pandas Series 和 Numpy array中的相同点
2019/06/28 Python
Django--权限Permissions的例子
2019/08/28 Python
将python包发布到PyPI和制作whl文件方式
2019/12/25 Python
python+Selenium自动化测试——输入,点击操作
2020/03/06 Python
python 图像插值 最近邻、双线性、双三次实例
2020/07/05 Python
Python 利用argparse模块实现脚本命令行参数解析
2020/12/28 Python
英国舒适型鞋履品牌:FitFlop
2017/05/17 全球购物
美国购物网站:Clickhere2shop
2021/01/28 全球购物
Linux机考试题
2015/10/16 面试题
银行财务部实习生的自我鉴定
2013/11/27 职场文书
高中生思想道德自我评价
2015/03/09 职场文书
初中同学会致辞
2015/08/01 职场文书
装修安全责任协议书
2016/03/22 职场文书