JavaScript 相等性判断详解:===、== 与 Object.is() 的区别
本文深入解析 JavaScript 中的三种值比较操作:严格相等(===)、宽松相等(==)以及 Object.is()。详细阐述了各运算符在类型转换、NaN、零值处理及对象引用上的具体逻辑,帮助开发者避免隐式转换陷阱,准确选择比较方式。
JavaScript 相等性判断概述
对于初学者而言,JavaScript 的相等性判断往往令人困惑。请观察以下代码片段,你能准确判断它们的输出结果吗?
NaN === NaN // false
NaN == NaN // false
Object.is(NaN, NaN) // true
0 == false // true
1 == true // true
Number(null) === 0 // true
null == 0 // false
JavaScript 提供了三种不同的值比较机制:严格相等(===)、宽松相等(==)以及 Object.is()。通过下文的内容,我们将彻底厘清它们的判断逻辑。
严格相等(===)逻辑
1. 严格相等(===)的判断逻辑
1. 如果 x 的数据类型与 y 的数据类型不同,则直接返回 false;
2. 如果 x 是 Number 类型:
- 若 x 为 NaN,返回 false;
- 若 y 为 NaN,返回 false;
- 若 x 的值与 y 的值相等,返回 true;
- 若 x 为 +0 且 y 为 -0,返回 true;
- 若 x 为 -0 且 y 为 +0,返回 true;
- 其他情况返回 false。
3. 对于非 Number 类型,参照 SameValueNonNumber(x, y) 规则:
- 断言:x 和 y 均不是 Number 类型;
- 断言:x 和 y 的数据类型相同;
- 若 x 是 undefined,y 也是 undefined,返回 true;
- 若 x 是 null,y 也是 null,返回 true;
- 若 x 是字符串类型,仅当 x 和 y 的字符序列完全相同时(即长度相同且每个位置上的字符一致)返回 true,否则返回 false;
- 若 x 是布尔类型,当 x 和 y 均为 true 或均为 false 时返回 true,否则返回 false;
- 若 x 是 symbol 类型,当 x 和 y 是相同的 symbol 值时返回 true,否则返回 false;
- 若 x 和 y 指向同一个对象值,返回 true,否则返回 false;
NaN === NaN // false
undefined === undefined // true
null === null // true
undefined === null // false
宽松相等(==)逻辑
2. 宽松相等(==)的判断逻辑
- 如果 x 和 y 的类型相同,直接返回 x === y 的结果;
- 如果 x 是 null 且 y 是 undefined,返回 true;
- 如果 x 是 undefined 且 y 是 null,返回 true;
- 如果 x 是数值,y 是字符串,返回 x == ToNumber(y);
- 如果 x 是字符串,y 是数值,返回 ToNumber(x) == y;
- 如果 x 是布尔类型,返回 ToNumber(x) == y 的结果;
- 如果 y 是布尔类型,返回 x == ToNumber(y) 的结果;
- 如果 x 是 String、Number 或 Symbol 中的一种,且 Type(y) 是 Object,返回 x == ToPrimitive(y) 的结果;
- 如果 Type(x) 是 Object,且 y 是 String、Number 或 Symbol 中的一种,返回 ToPrimitive(x) == y 的结果;
- 其他情况返回 false。
12 == '0xc' // true, 0xc是16进制
12 == '12' // true
12 == '12c' // false, 说明ToNumber转换是用的Number()方法
注意:
Number(null) === 0
但是
null == 0 // false,

ToNumber 转换规则
2.1 ToNumber 用于将一个值转换为数值类型。
具体细节参考数值类型转换规则:
- 如果是 boolean 类型,true 转换为 1,false 转换为 0;
- 如果是数值,直接原样返回;
- 如果是 null,返回 0;
- 如果是 undefined,返回 NaN;
- 如果是字符串,若字符串仅包含数字,则将其转换为十进制数;若是有效的浮点格式,转换为对应的浮点数值;若是二进制或十六进制,则转换为对应的十进制数值;
- 如果是对象,调用对象的 valueOf() 方法,然后依照前述规则转换;如果 valueOf 返回值是 NaN,则调用 toString() 方法,再依照前述规则转换返回的字符串。
ToPrimitive 转换规则
2.2 ToPrimitive
ToPrimitive(A) 通过尝试调用 A 的 toString() 和 valueOf() 方法,将参数 A 转换为原始值(Primitive)。JS 中的原始类型包括:Number、String、Boolean、Null、Undefined。
不同类型对象的 valueOf() 方法返回值如下:
| 对象 | 返回值 |
|---|---|
| Array | 返回数组对象本身。 |
| Boolean | 布尔值 |
| Date | 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC |
| Function | 函数本身 |
| Number | 数字值 |
| Object | 对象本身。这是默认情况, 可以覆盖自定义对象的valueOf方法 |
| String | 字符串值 |
// Array:返回数组对象本身
var array = ["ABC", true, 12, -5];
console.log(array.valueOf() === array); // true
// Date:当前时间距1970年1月1日午夜的毫秒数
var date = new Date(2013, 7, 18, 23, 11, 59, 230);
console.log(date.valueOf()); // 1376838719230
// Number:返回数字值
var num = 15.26540;
console.log(num.valueOf()); // 15.2654
// 布尔:返回布尔值true或false
var bool = true;
console.log(bool.valueOf() === bool); // true
// new一个Boolean对象
var newBool = new Boolean(true);
// valueOf()返回的是true,两者的值相等
console.log(newBool.valueOf() == newBool); // true
// 但是不全等,两者类型不相等,前者是boolean类型,后者是object类型
console.log(newBool.valueOf() === newBool); // false
// Function:返回函数本身
function foo(){}
console.log( foo.valueOf() === foo ); // true
var foo2 = new Function("x", "y", "return x + y;");
console.log( foo2.valueOf() );
/*
ƒ anonymous(x,y
) {
return x + y;
}
*/
// Object:返回对象本身
var obj = {name: "张三", age: 18};
console.log( obj.valueOf() === obj ); // true
// String:返回字符串值
var str = "http://www.xyz.com";
console.log( str.valueOf() === str ); // true
// new一个字符串对象
var str2 = new String("http://www.xyz.com");
// 两者的值相等,但不全等,因为类型不同,前者为string类型,后者为object类型
console.log( str2.valueOf() === str2 ); // false
Object.is 同值相等
3. 同值相等
同值相等由 Object.is 方法判断:
- 两个值都是 undefined;
- 两个值都是 null;
- 两个值都是 true 或者都是 false;
- 两个值是由相同个数的字符按照相同的顺序组成的字符串;
- 两个值指向同一个对象;
- 两个值都是数字并且
- 都是正零 +0,
- 或者都是负零 -0,
- 或者都是 NaN;
- 都是除零和 NaN 外的其它同一个数字。
Object.is('foo', 'foo'); // true
Object.is(window, window); // true
Object.is('foo', 'bar'); // false
Object.is([], []); // false
var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false
Object.is(null, null); // true
Object.is(true, 'true') // false
// 特例
Object.is(0, -0); // false
Object.is(0, +0); // true
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true
零值相等与总结
4. 零值相等
与同值相等类似,不过会认为 +0 与 -0 相等。
小结
=== 不做类型转换,当两边的数类型不相同时,直接返回 false;当前类型相同且都是数值类型的时候,有一个是 NaN,那么结果就是 false,另外 +0 === -0 返回 true。
== 运算符,当两边操作数类型不相同时会做隐式转换,然后才进行比较,这样的话就会出现 false == 0, '' == false 等现象,但是 Object.is 不会做这种转换。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对本站的支持。
JS动态构建复杂嵌套JSON对象的方法
2026-11-05 15:41:52
JS负数取余为什么是负数?详解余数与模运算区别
2026-11-05 13:34:41
JS 解压出现乱码或报错怎么解决?
2026-11-05 12:32:38
JS 中 startsWith、indexOf 与正则判断字符串前缀的对比
2026-11-04 22:19:43
JS解析Excel后怎么将数据转换为JSON格式
2026-11-04 20:58:28
