MYTEST / JAVASCRIPT

JavaScript equality
7 个回归测试用例

NaN: === is false; Object.is is true. Signed zero: the reverse.
NaN 与自身不严格相等;Object.is 认为相等。正负零则相反。

A small fixture for checking a comparison refactor or a surprising Jest assertion. Every result below is an exact boolean, not a tolerance check. These seven cases are a starter suite, not exhaustive coverage.
用于检查比较逻辑重构或排查 Jest 断言差异。下表给出精确布尔值,不做近似比较。七个用例仅是起点,并未穷尽所有情况。

Each row compares a with b / 每行比较 a 与 b
a / ba == ba === bObject.is(a, b)[a].includes(b)
NaN / NaNfalsefalsetruetrue
+0 / -0truetruefalsetrue
0 / "0"truefalsefalsefalse
null / undefinedtruefalsefalsefalse
[] / []falsefalsefalsefalse
shared / sharedtruetruetruetrue
0.1 + 0.2 / 0.3falsefalsefalsefalse

The last column uses SameValueZero: no type coercion, NaN equals itself, and +0 equals -0. “shared” means the same object in both positions.
最后一列使用 SameValueZero:不做类型转换,NaN 等于自身,正负零相等。shared 表示同一对象引用。

Copy the runnable fixture / 复制可运行样例

Copy the regression fixture / 复制回归样例

Save this as a .js file and run it with Node, or paste it into your own development console. Success prints “Passed 7 cases / 28 equality assertions”; a mismatch throws an error. This page only copies the fixed text and never runs it.
保存为 .js 文件后用 Node 运行,也可在自己的开发控制台运行。全部通过时输出上面的英文结果,有差异时抛出错误。本页只复制固定文字,不执行样例。

You can also select the source and copy manually. / 也可以选择源码手动复制。

When this catches a test bug

Jest’s toBe uses Object.is. So expect(NaN).toBe(NaN) passes, while expect(+0).toBe(-0) fails. This differs from ===. Jest’s toContain uses strict equality; it does not share Array.prototype.includes’ NaN behavior.

Done with this check? An optional rock–paper–scissors break: try privately (no nickname or quiz), read the guide or watch existing games (read-only). All open in a new tab; opening a link does not play a hand.

These are identity/equality checks, not deep comparisons. Distinct arrays stay unequal even if their contents match. For an approximate numeric requirement, choose a tolerance suited to the values and application; Jest provides toBeCloseTo. Replacing === with Object.is does not fix decimal rounding.

Keep the fixture as JavaScript, not JSON

JSON.stringify([NaN, -0, undefined]) gives "[null,0,null]". In objects, a property with value undefined is omitted; a top-level undefined returns no JSON string. JSON also does not preserve shared object identity. A JSON round trip silently changes what these cases test.

这些用例能抓住什么问题

Jest 的 toBe 使用 Object.is。因此 expect(NaN).toBe(NaN) 通过,而 expect(+0).toBe(-0) 失败,这与 === 不同。Jest 的 toContain 使用严格相等;它处理 NaN 的方式与 Array.prototype.includes 不同。

检查告一段落?可以自愿休息一下,看看猜拳小游戏:私下试玩(无需昵称或答题)、阅读指南或只读围观现有对局。均在新标签页打开,不会自动出拳。

这里比较值或对象引用,不做深度比较。即使内容一样,两个独立数组仍不相等。需要近似数值比较时,应按数值规模和业务要求选择容差;Jest 提供 toBeCloseTo。把 === 换成 Object.is 并不能修复小数舍入误差。

样例保留为 JavaScript,不要转成 JSON

JSON.stringify([NaN, -0, undefined]) 得到 "[null,0,null]"。对象中值为 undefined 的属性会被省略;顶层 undefined 不返回 JSON 字符串。JSON 也不会保留共享对象引用。转成 JSON 再解析,会悄悄改变这些用例实际测试的内容。

Why each row differs / 逐行解释

  1. NaN / NaNNaN matches itself only in SameValue and SameValueZero.NaN 只在 SameValue 和 SameValueZero 中与自身相等。
  2. +0 / -0Object.is distinguishes the sign of zero.Object.is 区分正零和负零。
  3. 0 / "0"Only == coerces the string to a number here.这里仅 == 会将字符串转换为数字。
  4. null / undefinedLoose equality treats this nullish pair as equal.宽松相等将这对空值视为相等。
  5. [] / []Two distinct arrays are different references; contents do not matter.两个独立数组引用不同;不会逐项比较内容。
  6. shared / sharedBoth operands refer to the same object: const shared = {}.两边引用同一个对象:const shared = {}。
  7. 0.1 + 0.2 / 0.3The binary floating-point sum is not exactly 0.3.二进制浮点运算的结果并不精确等于 0.3。

Reference details / 官方说明