JavaScript中的相等判断

JavaScript中有四种相等性的判断算法:

  • ==宽松相等
  • ===严格相等
  • 同值相等(-0 !== +0) NaN === NaN
  • 零值相等(-0 === +0)

JavaScript中相等性判断的方法:

  • ===严格相等(strict equality)
  • ==非严格相等(抽象/非约束)相等(loose equality)
  • Object.is(v1, v2)
严格相等
  • 不进行隐式类型转换,若比较的两个操作数类型相同,值也相同,则结果为true
1 === '1' ? false
1 === 2 ? false
  • 引用值为同一地址,结果为true
var obj = {}
obj === obj ? true
{} === {} ? false
  • NaN和任何值都不相等,包括它本身
NaN === NaN ? false
NaN === undefined ? false
  • +0-0相等
  • +Infinity-Infinity不相等

延伸:如何定义一个变量a,使得a !== a的结果为true?答:将a设为NaN。

非严格相等
  • 两个操作数在进行非严格相等判断之前会先进行隐式类型转换,转换以后还是用严格相等===来进行比较,具体比较规则如下:
    JavaScript中的相等判断_第1张图片

ToPrimitive(A)通过尝试调用 A 的A.toString() 和 A.valueOf() 方法,将参数 A 转换为原始值(Primitive)

  • 任何对象都与undefinednull不相等
({}) == undefined ? false
({}) == null ? false
同值相等(same-value)
  • 同值相等中会认为+0 !== -0,可利用Object.defineProperty()验证,例如
var obj = {}
// 给obj定义一个属性a
Object.defineProperty(obj, 'a', {
  value: -0,
  writable: false,
  configurable: false,
  enumerable: false
})

// 再对obj对象操作a属性,因为a是不可变属性,所以如果设置的值不同,会报错
Object.defineProperty(obj, 'a', {
  value: +0,  // 报错
  writable: false,
  configurable: false,
  enumerable: false
})
  • 同值相等中认为NaN === NaN,同样可利用Object.defineProperty()验证:
var obj = {}
// 给obj定义一个属性a
Object.defineProperty(obj, 'a', {
  value: NaN,
  writable: false,
  configurable: false,
  enumerable: false
})

Object.defineProperty(obj, 'a', {
  value: NaN,  // 不报错
  writable: false,
  configurable: false,
  enumerable: false
})
  • 同值比较底层实现使用的是Object.is()方法,只是ES6把这个方法暴露了出来
  • 手写Object.is()的实现
function myObjectIs(a, b) {
  /* 
  判断如果a===b为true,需要分两种情况:
    两者都不为0,则在判断a !== -0 结果直接返回true
    两者为0,如果一个为-0,一个为+0,则1/-0 === -Infinity,1/+0 === +Infinity,1/-0 === 1/+0 结果返回false
  */
  if(a === b) {
    return a !== -0 || (1/a === 1/b)
  }
  /* 
  若两者不相等,分两种情况:
    两者都不为NaN,则a !== a && b !== b返回false
    两者都为NaN,则a !== a && b !== b返回true
  */
  return a !== a && b !== b
}
零值相等
  • 零值相等与同值相等一样,但是会认为-0 === +0结果为true

===判断和Object.is()判断的区别在对-0+0NaNNaN判断的结果不一样。

你可能感兴趣的:(前端,javascript)