跳到主要内容

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

值对比取决于 2 个因素

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

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

什么是类型转换?

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

比较运算符的种类

JavaScript 提供了 3 种比较运算符:

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

==(非严格相等)

  • 其被称为相等操作符,只会对比两个值是否相等,相等则会返回 true
  • 在这种情况下,如果对比的值类型不同,则会自动将值隐式转换成一种常见的类型
console.log(1 == "1"); // true
console.log(true == "true"); // false
console.log(NaN == "NaN"); // false
console.log(NaN == NaN); // false
console.log(-0 == 0); // true
console.log(0 == "0"); // true
console.log({ name: "Tom" } == { name: "Tom" }); // false

const a = { name: "Tom" };
const b = a;
console.log(a == b); // true

使用==总结

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

===【严格相等】

  • 其被称为 全等操作符,和 == 很相似,区别在于 === 不执行隐式转换
  • 当两个操作值的值和类型都相等的情况下,才会返回 true
console.log(1 === "1"); // false
console.log(true === "true"); // false
console.log(true === true); // true
console.log(NaN === NaN); // false
console.log(null === null); // true
console.log("ara" == "Ara"); //false
console.log(-0 === 0); // true
console.log(null === undefined); // false
console.log({ name: "Tom" } === { name: "Tom" }); // false

使用===总结

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

Object.is()

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

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

let a;
let b;
Object.is(a, b); // true

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

Object.is("abcdefg", "abcdefg"); // true
Object.is("abcdefg", "ABCDEFG"); // false

规则 3:操作值都是 null

Object.is(null, null); // true
Object.is(null, "null"); // false

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

let a = { name: "Tom" };
let b = a;

Object.is(a, b); // true
Object.is({ name: "Tom" }, { name: "Tom" }); // false
Object.is(window, window); // true

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

Object.is(1, 1); // true
Object.is(1, 2); // false

规则 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

polyfill

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

if (!Object.is) {
Object.is = function (a, b) {
if (a === b) {
return a !== 0 || 1 / a === 1 / b;
} else {
return a !== a && b !== b;
}
};
}