javascript中的同值相等

81 阅读1分钟

同值相等解决了确定两个值是否在任何情况下功能上是相同的这个问题

Object.is

ES5提供的同值相等,只用在js引擎内部使用,ES6中通过Object.is对暴露出这个方法,Object.is 的行为方式与严格相等相同,但是对于 NaN 、-0 和 +0 进行特殊处理。

使用场景

  • 需要特殊处理NaN的情况
Object.is(NaN,NaN) // true
NaN === NaN // false
  • 需要特殊区分-0 和 +0的情况

例如需要模拟Object.defineProperty的一些特性时可以使用Object.is Object.defineProperty 在试图修改不可变属性时,如果这个属性确实被修改了则会抛出异常,反之什么都不会发生。 例如如果 v 是 -0 ,那么没有发生任何变化,所以也不会抛出任何异常。但如果 v 是 +0 ,则会抛出异常。不可变属性和新设定的值使用 same-value 相等比较

注意

如果使用Object.is,需要注意一些会区分对待+0,-0的情况

  • - (一元负)
const bar = { baz: -0, foobar: 1, barfoo: 0 };

// 表达式的抽象化可能在你没有意识到得情况下导致-0 延续传播

const foo = bar.foobar * -bar.barfoo // -0
  • Math.atan2Math.ceilMath.pow,Math.round
// 计算`-Infinity`的任何负奇指数的幂都会得到-0
Math.pow(-Infinity, -3) // -0
Math.ceil(-0.95) // -0
Math.round(-0.1) // -0
Math.atan2( ±0, +0 ) ±0     
  • Math.floorMath.maxMath.minMath.sin,Math.sqrtMath.tan
Math.min(-0, +0) // -0
Math.max(-0, -1) // -0
Math.floor(-0) // -0
Math.sin(-0) // -0
  • ~<<>>
  • 这些操作符内部都使用了 ToInt32 算法。因为内部 32 位整数类型只有一个 0(没有符号区别),-0 的符号在反操作后并不会保留下来。
Object.is(~~(-0), -0) // false
Object.is(-0 << 2 >> 2, -0) // false