阅读 178

【译】 == vs === vs Object.is()

img
原文地址

大家是否和我一样有遇到过由于运算符(==)而引起的程序问题,但是为什么会造成这种问题呢?

值对比取决于2个因素

  • 所操作的值
  • 值的类型,如String, Boolean,……

在值对比时还有一个起着重要的作用的机制,那就是值类型转换

什么是类型转换呢?

JavaScript作为一个弱类型语言,有时候值会从一个类型转换为其他类型,这被称为隐式转换或者强制转换,这些在我们使用运算符(==)时会导致一些错误发生。

比较运算符的种类

JavaScript提供了3中比较运算符

  • ==
  • ===
  • Object.is()

==【非严格相等】

  • 其被称为相等操作符,只会对比两个值是否相等,相等则会返回true
  • 在这种情况下,如果对比的值类型不同,则会自动将值隐式转换为一种常见的类型

示例

console.log(1 == '1')  // true
console.log(true == 'true') // false[原文中是true,但试了是false]
console.log(NaN == 'NaN') // false
console.log(NaN == NaN) // false [这点是关键,NaN和NaN永不相等]
console.log(-0 == 0) // true
console.log(0 == '0') // true
console.log({"name": "Arwa"} == {"name": "Arwa"}) // false[引用内存地址不同]

let a = {"name": "Arwa"}
let b = a
console.log(a == b) // true[引用的内存地址一样]
复制代码

使用==总结

  • NaN不等于包含它在内的任何东西
  • -0与0相等
  • null等于nullundefined
  • 操作值可以自动转换为StringBooleanNumber
  • String类型比较区分大小写
  • 两个操作值如果引用同一个对象,返回true,否则false
  • 请记住6个虚值(null, undefined, `` , 0 , NaN , false)

===【严格相等】

  • 其被成为全等操作符("triple equals" 或 "identity"),和==很相似,区别在于===不执行隐式类型转换
  • 当两个操作值的值与类型都相等的前提下,才会返回true

示例

console.log(1 === '1') // false, 值类型不同,Number vs String
console.log(true === 'true') // false, 同上
console.log(true === true) // true,都是Bollean
console.log(NaN === NaN) // false,NaN永远不等于NaN
console.log(null === null) // true
console.log('Ara' === 'ara') // false,严格区分大小写
console.log(-0 === 0) // true
console.log(null === undefined) // false
console.log({"name": "Arwa"} == {"name": "Arwa"}) // false,原因也是内存地址不同
复制代码

使用===总结

  • NaN不等于包含它在内的任何东西
  • -0等于0
  • null等于null,但不等于undefined
  • String严格区分大小写
  • 两个操作值如果引用同一个对象,返回true,否则false

Object.is()

Syntax: Object.is(value 1, value 2)

  • 其被称为同值相等,是比较运算符中的一份子
  • 在检查两个操作值是否相等时,用到了一下规则

规则1:操作值均未被定义(undefined)

示例

let a
let b
Object.is(a,b) // true
复制代码

规则2:操作数都是相同长度和顺序的字符串

示例

Object.is('Comparison Operators', 'Comparison Operators') // true
// 然而
Object.is('Comparison Operators', 'comparison Operators') // false, 严格区分大小写
复制代码

规则3:操作值均为null

示例

Object.is(null, null) // true
Object.is(null, 'null') // false
复制代码

规则4:操作值为对象且引用地址相同

示例

let a = {"name": "Arwa"}
let b = a

Object.is(a, b) // true

Object.is({"name": "Arwa"}, {"name": "Arwa"}) // false

Object.is(window, window) // true,均引用了同一个全局变量
复制代码

规则5:操作值均未非0和非NaN数

示例

Object.is(1,1) // true
复制代码

规则6:操作值都是+0或-0

示例

Object.is(0,0) // true
//但是
Object.is(0, -0) //false,这点就不同于==和===
复制代码

规则7:操作值为NaN

示例

Object.is(NaN, NaN) // true,这点也和==和===不同
Object.is(NaN,0/0) // true
复制代码

注意:Object.is()不支持IE,因此请使用polyfill代替

小细节

你知道下面函数中使用了哪一个比较运算符

Array.prototype.indexOf()

答案是使用了===

更多关于对比运算符

如果想了解更多,MDN上给了很多关于这些运算符的例子,这对初学者很有帮助的!

比较运算符
表达式和运算符

总结

这三个比较运算符都非常有用,当进行一些普遍的比较时,则推荐使用===,而不是==
当遇到NaN、0、+0、-0较为特殊当比较时,还是推荐使用Object.is()(切记兼容性)

为什么你应该在相等比较中使用 Object.is()

初次翻译,存在不对的地方还请大家指正!会努力改正!🆚

关注下面的标签,发现更多相似文章
评论