《Effective JavaScript》​- 1.5 避免对混合类型使用 == 运算符

这里写图片描述

我们看看下面的表达式是什么?

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

这两个看似无关的值使用==运算符实际上是相等的。就像1.3描述的隐式强制转换一样,在比较之前,他们都被解析为数字1,而匿名对象也通过valueOf方法得到的结果为true,然后再转换为数字,得到1。
很容易使用这些强制转换完成一些工作。例如,从一个Web表单读取一个字段并与一个数字进行比较。

var today = new Date();

if (form.month.value == (today.getMonth() + 1) && form.day.value == today.getDate()) {
    //happy birthday!
    //...
}

但实际上,它只是显式地使用Number函数或者一元运算符 + 将值转换为数字。

var today = new Date();

if (+form.month.value == (today.getMonth() + 1) && +form.day.value == today.getDate()) {
    //happy birthday!
    //...
}

转换测试:

var num = '1';
console.log (typeof  num) // string
console.log (typeof +num) // number

一个更好的替代方式是使用严格的相等运算符 ===。

var today = new Date();

if (+form.month.value === (today.getMonth() + 1) && +form.day.value === today.getDate()) {
    //happy birthday!
    //...
}

当两个参数属于同一类型时, == 和 === 运算符的行为是没有区别的。但最好还是使用严格的相等运算符, 因为读者会非常清晰地知道: 在比较操作中并没有涉及任何转换。否则,我们需要读者准确地记住这些强制转换规则以解读代码的行为。
事实上,这些强制转换规则一点也不明显。表1.1包含了 == 运算符针对不同类型参数的强制转换规则。这些规则具有对称性。例如,第一条规则既适用于null == undefined,也适用于undefined == null。在很多时候, 这些转换都试图产生数字。 但当他们处理对象时会变得难以捉摸。 操作符试图将对象转换为原始值, 可通过调用对象的valueOf 和 toString 方法而实现。 更令人难以捉摸的是, Date对象以相反的顺序尝试调用这两个方法。

这里写图片描述

==运算符将数据以不同的表现呈现出来, 这种纠错方式有时称为“照我的意思去做”(do what I mean)的语义。但计算机并不能真正地了解我们的心思。世界上有太多的数据表现形式,JavaScript需要知道我们使用的是哪种。例如,我们可能希望能将一个包含日期的字符串和一个Date对象进行比较。

var date = new Date('1999/12/31');
date == '1999/12/31' // false

这个例子失败是因为Date对象被转换成一种不同格式的字符串, 而不是本例所采用的格式。

date.toString(); // Fri Dec 31 1999 00:00:00 GMT+0800

但是,这种错误是一个更普遍的强制转换误解的“症状”。==运算符并不能推断和统一所有的数据格式。它需要我们和读者都能理解其微妙的强制转换规则。更好的策略是显式自定义应用程序转换的逻辑,并使用严格相等运算符。

var date = new Date('1999/12/31');

function toYMD (date) {
    var y = date.getYear() + 1900, //year is 1900-indexed
        m = date.getMonth() + 1, //month is 0-indexed
        d = date.getDate();
    return y + '/' + (m < 10 ? '0' + m : m) + '/' + (d < 10 ? '0' + d : d);
}

toYMD(date) === '1999/12/31'; // true

显式地定义转换的逻辑能确保我们不会混淆==运算符的强制转换规则, 而且免除了读者不得不查找或记住这些规则的麻烦。

提示

  • 当参数类型不同时, == 运算符应用了一套难以理解的隐式强制转换规则。
  • 使用 === 运算符, 使读者不需要涉及任何的隐式强制转换就能明白我们的比较运算。
  • 当比较不同类型的值时, 使用我们自己的显式强制转换使程序的行为更清晰。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值