JavaScript 相等操作符(==)的隐式转换规则与对象比较详解
本文详细解析 JavaScript 中相等操作符(==)的工作机制。重点阐述其在比较不同数据类型时的隐式转换规则,包括布尔值、字符串、数值及对象的转换逻辑。同时深入探讨引用类型在堆内存中的地址比较,解释为何 {} == {} 和 [] == [] 返回 false,以及逻辑非运算符优先级对比较结果的影响。
相等操作符的基本定义与转换机制
在 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 均属于引用类型。
声明引用类型变量时,变量名存储在 JavaScript 的栈内存中,而对应的实际值存储在堆内存中。
栈内存中保存的实际上是堆内存中值的地址,即指针。
var a = {}; var b = {};
在上述代码中,声明变量 a 时,堆内存中创建了一个 Object 实例,变量 a 保存的是该 Object 在堆内存中的地址。
接着声明变量 b 时,又在堆内存中创建了一个新的 Object 实例。
尽管 a 和 b 都引用了 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,要用“!=”。对象和非对象在进行比较的时候会先转为基本类型值然后再根据上面的规则进行比较。
定制 Quill.js 主题样式:修改默认 CSS 与添加自定义类名
2026-11-04 11:21:35
混淆JS代码怎么在线反混淆并格式化阅读
2026-11-03 21:46:39
JS在线编辑器代码报错怎么调试?控制台使用技巧
2026-11-03 21:24:56
从 marked.js 旧版本升级到最新版:API 变更与迁移指南
2026-11-03 17:38:17
JS富文本编辑器Quill与代码编辑器CodeMirror的区别及应用场景
2026-11-03 16:52:09
