yliu

时来天地皆同力,运去英雄不自由

相等运算符比较


看《你所不知道的JavaScript》一书,发现对相等运算符的描述推翻了许多人的固有影响,如果熟悉其机制,可以方便我们快速开发

function foo(s) {
  s = s == null ?  true: s;
  // ...
};

上面这段代码我们估计经常使用,其实就是使用了隐式转换,下面就来聊聊相等运算符

规则

  1. 数值与字符串比较,转化为数值比较
42 == "42";
// 等于
42 == Number("42");
  1. 布尔型与其他类型比较,转化为数值,之后比较
"42" == true;
// 等于
"42" == Number(true);
"42" == 1;
Number("42") == 1;
  1. undefined 只与 null 相等,其他返回 false
// 全部false
null == false;
null == true;
null == "";
null == 0;
undefined == true;
undefined == false;
undefined == "";
undefined == 0;
  1. 对象 对象与基本类型比较,会将对象转化为基本类型之后再进行比较; 转化规则很简单,默认调用 valueOf,如果返回不是基本类型继续调用 toStirng,如果返回还不是基本类型会报错。
[42] == 42;
// 等于
"42" == 42;
Number("42") == 42;

"abc" == new String("abc");
// 等于
"abc" == "abc";

根据对象转化规则,我们自定义返回的值,比如:

var a = [];
a.valueOf = function() {
  return 42;
};
a.toString = function() {
  return "123";
};
a == 42; //true

实战

上面简单介绍了一下规则,再来看一下隐形的问题

  1. [] = ![] 这里会返回 true 原因很简单,根据上述规则其实也就是"" == 0比较
  2. 0 == '\n' 这里会返回 true,因为空格和一些其他制表符会被忽略掉。 再来看一些常见的陷阱
"0" == false; // true
false == 0; // true
false == ""; // true
false == []; // true
"" == []; // true
0 == []; // true
"" == 0; // true
  1. [null] == "" 这里为true,可能你在想[null]返回的不就是字符串 null 么,不过很遗憾,null 和 undefined,在数组中转化为字符串为"",这是 JavaScript 所规定的。
[null] == "";
// 转化为
"" == "";

最后

// a可能为true执行下去么
if (a == 2 && a == 3) {
  // 执行里面的代码
}