5.避免对混合类型使用 == 运算符

"1.0e0" == { valueOf:function() { return true; } }; // true

在比较之前它们都被转换为数字,字符串"1.0e0"被解析为数字1,而匿名对象也通过调用自身的valueOf方法得到结果true,然后再转换为数字,得到1。
很容易使用这些强制转换完成一些工作。

var today = new Date();
if (form.month.value == (today.getMonth() + 1) && form.day.value == today.getDate()){
  // happy birthday!
  // ...
}
// 等效于
var today = new Date();
if (+form.month.value == (today.getMonth() + 1) && +form.day.value == today.getDate()){
  // happy birthday!
  // ...
}
// 等效于
var today = new Date();
if (+form.month.value == (today.getMonth() + 1) && +form.day.value == today.getDate()){
  // happy birthday!
  // ...
}
// 当两个参数属于同一类型时,==和===运算符的行为是没有区别的,如果参数属于同一类型,那么==和===运算符可以互换,但最好使用严格相等运算符。

== 运算符的强制转换规则

参数类型1 参数类型2 强制转换
null undefined 不转换,总是返回true
null 或 undefined 其他任何非 null 或 undefined 的类型 不转换,总是返回 false
string、number 或 boolean Date 对象 将原始类型转换为数字;将 Date 对象转换为原始类型(优先尝试 toString 方法,再尝试 valueOf 方法)
string、number 或 boolean 非 Date 对象 将原始类型转换为数字;将非 Date 对象转换为原始类型(优先尝试用 valueOf 方法,再尝试 toString 方法)
string、number 或 boolean string、number 或 boolean 将原始类型转换为数字

== 运算符并不能推断和统一所有的数据格式

var date = new Date("2017/12/12");
data == "2017/12/12"; // false
date.toString(); // "Tue Dec 12 2017 00:00:00 GMT+0800 (CST)"

更好的策略是显式自定义应用程序转换的逻辑,并使用严格相等运算符

function toYMD(date) {
 var y = date.getYear() + 1900, // 年从1900开始计数
      m = date.getMonth() + 1, // 月从0开始计数
       d = date.getDate();
 return y + "/" + (m < 10 ? "0" + m : m) + "/" + (d < 10 ? "0" + d : d); 
}
toYMD(date) === "2017/12/12"; // true
// 显式地定义转换的逻辑能确保你不会混淆 == 运算符的强制转换规则,而且免除了读者不得不查找或记住这些规则的麻烦。

提示

  • 当参数类型不同时,== 运算符应用了一套难以理解的隐式强制转换规则。
  • 使用 === 运算符,使读者不需要涉及任何隐式强制转换就能明白你的比较运算。
  • 当比较不同类型的值时,使用你自己的显式强制转换使程序的行为更清晰。

你可能感兴趣的:(5.避免对混合类型使用 == 运算符)