各位朋友,大家好!今天咱们不聊家长里短,就聊聊JavaScript里一个有点意思的函数:Object.is()
。这玩意儿听着好像很高大上,其实就是个判断俩值是不是“绝对相等”的。但它又跟我们常用的===
(严格相等)运算符有点不一样,区别就在于它对+0
、-0
和NaN
的处理上。
咱们先来个热身,回顾一下===
:
console.log(1 === 1); // true
console.log("hello" === "hello"); // true
console.log(null === null); // true
console.log(undefined === undefined); // true
console.log({} === {}); // false (因为是不同的对象引用)
console.log([] === []); // false (同样因为是不同的数组引用)
===
比较的是值和类型,如果类型不同,直接返回 false
。如果类型相同,再比较值。对于对象和数组,比较的是引用是否相同,而不是内容是否相同。
现在,Object.is()
登场!
Object.is()
的基本用法
Object.is(value1, value2)
接受两个参数,返回一个布尔值,表示这两个值是否“绝对相等”。
console.log(Object.is(1, 1)); // true
console.log(Object.is("hello", "hello")); // true
console.log(Object.is(null, null)); // true
console.log(Object.is(undefined, undefined)); // true
console.log(Object.is({}, {})); // false (和 === 一样,比较的是引用)
console.log(Object.is([], [])); // false (和 === 一样,比较的是引用)
到目前为止,Object.is()
看起来和 ===
没什么区别,对不对? 别急,好戏还在后头。
Object.is()
的特别之处:+0
和 -0
在JavaScript里,+0
和 -0
是两个不同的值,虽然它们在数值上都表示零。 ===
认为它们是相等的:
console.log(+0 === -0); // true
但是,Object.is()
区分了它们:
console.log(Object.is(+0, -0)); // false
这有什么用呢? 在一些特定的数学运算或者算法中,+0
和 -0
的符号是有意义的,区分它们可以帮助我们避免一些潜在的错误。 举个例子,计算 1 / x
的结果时,如果 x
是 +0
,结果是 Infinity
;如果 x
是 -0
,结果是 -Infinity
。
console.log(1 / +0); // Infinity
console.log(1 / -0); // -Infinity
如果你的程序依赖于这种符号差异,那么 Object.is()
就能派上用场了。
Object.is()
的另一个特别之处:NaN
NaN
(Not a Number) 是 JavaScript 中一个特殊的值,表示一个非数字的结果。 NaN
有一个奇怪的特性:它和任何值都不相等,包括它自己!
console.log(NaN === NaN); // false
这让人很困惑,因为我们通常认为一个东西应该和它自己相等。 Object.is()
修正了这个问题:
console.log(Object.is(NaN, NaN)); // true
Object.is()
认为 NaN
和 NaN
是相等的。 这使得在某些情况下更容易判断一个值是否为 NaN
。
Object.is()
的应用场景
虽然 Object.is()
看起来只是对 ===
的一个小小的补充,但在某些情况下,它能提供更精确的相等性判断。
-
需要区分
+0
和-0
的情况: 如前所述,在一些数学运算或算法中,+0
和-0
的符号是有意义的。 -
需要正确判断
NaN
的情况: 由于NaN
不等于自身,使用Object.is(NaN, NaN)
可以更可靠地判断一个值是否为NaN
。 当然,你也可以使用Number.isNaN()
函数,它专门用于判断一个值是否为NaN
。
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN(123)); // false
- 某些库或框架内部使用: 一些库或框架可能会使用
Object.is()
来实现更严格的相等性判断,以确保程序的正确性。
Object.is()
vs. ===
vs. ==
为了更好地理解 Object.is()
的作用,我们来对比一下 Object.is()
、===
(严格相等)和 ==
(相等)这三种相等性判断方式。
特性 | == (相等) |
=== (严格相等) |
Object.is() (绝对相等) |
---|---|---|---|
类型转换 | 会进行类型转换 | 不进行类型转换 | 不进行类型转换 |
+0 和 -0 |
认为相等 | 认为相等 | 认为不相等 |
NaN |
认为不等于自身 | 认为不等于自身 | 认为等于自身 |
使用场景 | 尽量避免使用,容易出错 | 常用,推荐使用 | 特殊场景,需要区分 +0 和 -0 ,以及正确判断 NaN |
==
是最宽松的相等性判断,它会进行类型转换。 由于类型转换的规则比较复杂,容易导致一些意想不到的结果,因此通常不建议使用。
console.log(1 == "1"); // true (字符串 "1" 会被转换为数字 1)
console.log(0 == false); // true (false 会被转换为数字 0)
console.log(null == undefined); // true
===
是更严格的相等性判断,它不会进行类型转换。 这是我们通常使用的相等性判断方式。
Object.is()
是最严格的相等性判断,它在 ===
的基础上,对 +0
、-0
和 NaN
进行了特殊处理。
手写一个 Object.is()
为了更好地理解 Object.is()
的实现原理,我们可以尝试手写一个简单的 Object.is()
函数:
function myObjectIs(x, y) {
if (x === y) {
// 针对 +0 和 -0 的情况
return x !== 0 || 1 / x === 1 / y;
} else {
// 针对 NaN 的情况
return x !== x && y !== y;
}
}
console.log(myObjectIs(1, 1)); // true
console.log(myObjectIs("hello", "hello")); // true
console.log(myObjectIs(+0, -0)); // false
console.log(myObjectIs(NaN, NaN)); // true
console.log(myObjectIs(NaN, 1)); // false
这个 myObjectIs()
函数首先判断 x
和 y
是否严格相等。 如果严格相等,再判断是否为 +0
和 -0
的情况。 如果不严格相等,则判断是否为 NaN
的情况。
总结
Object.is()
是 JavaScript 中一个用于判断两个值是否“绝对相等”的函数。 它在 ===
的基础上,对 +0
、-0
和 NaN
进行了特殊处理。
Object.is(+0, -0)
返回false
,而===
返回true
。Object.is(NaN, NaN)
返回true
,而===
返回false
。
Object.is()
在一些需要区分 +0
和 -0
,以及正确判断 NaN
的特殊场景中非常有用。
总的来说,===
是我们最常用的相等性判断方式。只有在需要处理 +0
、-0
和 NaN
的特殊情况下,才需要使用 Object.is()
。 就像工具箱里的扳手和螺丝刀,各有各的用途,用对了才能事半功倍!
今天就先聊到这儿,希望大家对 Object.is()
有了更深入的了解。 如果有什么问题,欢迎随时提问。 下次有机会,咱们再聊聊 JavaScript 里的其他有趣的东西!