• js宽松相等(==)最权威的执行过程讲解
  • 发布于 2个月前
  • 102 热度
    0 评论
还是那个不务正业、不写 JavaScript 的老友,不知道为什么研究起了 JavaScript 基础语法知识:

并自己尝试对以上这些现象做了规律总结。正确、完整的总结当然是在 ECMAScript 规范中(ecma262)啊:


说人话就是,x == y 会按下面的规则执行:
1.如果 x 和 y 类型相同,则执行严格相等操作( x === y )[规则1]
2.null 和 undefined 比较时,返回 true [规则2、3]
3.document.all 对象和 undefined/null 比较时,返回 true [规则4]
4.Number 和 String 比较时,先把 String 转成 Number 再比较 [规则5、6]
5.BigInt 和 String 比较时,其实和上条差不多,把 String 转为 BigInt 再比较,只是 String 转成 Number 时可能产生 NaN 而转为 BigInt 可能产生 undefined。若是转换时出现 undefined 则返回 false [规则7、8]
6.如果操作数存在 Boolen 类型,先转为 Number 再进行比较。此时,true 转为 1,false 转为 0[规则9、10]
7.如果一个操作数是对象,另一个是 String、Number、BigInt 或 Symbol 类型,则先将对象转为原始值再比较。[规则11、12]
8.Number 和 BigInt 比较时,是符合直觉的数学比较。举些特例来理解吧:1n == 1 为 true;Infinity == Infinity为 ture;Infinity 和任何非无穷的数比较都返回 false [规则13]
9.不符合以上情况的,统统返回 false [规则14]

其中,对象转为原始值操作的行为如下:
1.调用对象的 valueOf 方法。如果 valueOf 方法返回一个原始值,则返回该原始值。
2.否则,调用对象的 toString 方法。如果 toString 方法返回一个原始值,则返回该原始值。
3.如果以上步骤都没有返回原始值,则抛出一个 TypeError,表示无法将值转换为原始值

所以你会看到,'0' == 0 返回 true,'' == 0 也返回 true,但显然 '' == '0' 返回 false,==不具备推导性。你还会发现,false == '0' 会转为 0 =='0' 后再转为 0 == 0 进行比较,最终返回 true,如果你将页面中的 <input/> 值和 false 比较来验证非空输入的话,而用户输入了 0 时,会认为用户没输入。

再举些例子:
const foo = {
  valueOf() {
    return 42;
  },
  toString() {
    return "foo";
  }
};
foo == true  // false
foo == 42    // true
foo == 'foo' // false
foo == '42'  // true

const bar = {
  toString() {
    return 1;
  }
};
bar == true  // true
可以看出,==的使用规则还是挺复杂的,有什么简洁、快速、又准确地掌握它的方法吗?当然有,就是不使用它啊!
用户评论