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

是值是多少?

这两个完全不同的值使用==运算符是相等的。为什么呢?请看《[Effective JavaScript笔记]第3条:当心隐式的强制转换

因为这个会在比较之前对两个值都进行隐式转换。字符串“1.0e0”被解析成1,而{valueOf:function(){return true;}}会通过调用自身的valueOf进行转化得到true,然后再转化为数字,得到1;

很容易使用强制转换完成一些工作。如,从一个WEB表单读取一个字段并与一个数字进行比较。

var today=new Date();

if(form.month.value == (today.getMonth()+1)&&

form.day.value==today.getDate()){

//….

}

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

var today=new Date();

if(+form.month.value == (today.getMonth()+1)&&

+form.day.value==today.getDate()){

//….

}

上面的这段代码更清晰地传达了在做什么样的转换。

更好的方法是用严格相等运算符

var today=new Date();

if(+form.month.value === (today.getMonth()+1)&&

+form.day.value===today.getDate()){

//….

}

注:当两个参数属于同一类型时,==和===没有区别。最好是用严格相等运算符===,可以清晰表达比较,并不涉及到转换。

==运算符针对不同类型参数的强制转换规则:

  • 1、null  ==    undefined     说明:不转换总是返回true
  • 2、null或undefined  ==   其他任何非null或undefined的类型   说明:不转换,总是返回false
  • 3、原始类型:string、number或boolean ==  Date对象  说明:将原始类型转换为数字,将Date对象转换为原始类型(优先尝试toString方法,再尝试valueOf方法)
  • 4、原始类型:string、number或boolean ==  非Date对象   说明: 将原始类型转换为数字,将非Date对象转换为原始类型(优先尝试valueOf方法,再尝试toString方法)
  • 5、原始类型:string、number或boolean ==  原始类型:string、number或boolean   说明:将原始类型转换为数字

==运算符将数据以不同的表现呈现出来,但计算机并不能真正地了解你的选择,因为有太多的数据表现形式,js需要知道你使用的是哪种。

例如:

这里的date转换成了“Mon May 09 2016 00:00:00 GMT+0800 (中国标准时间)”这种格式。

==不能推断和统一所有的数据格式。它需要你理解其微妙的强制转换规则。最好的策略是显式自定义应用程序转换的逻辑,并使用严格相等运算符===

function toYMD(date){
     var y=date.getYear()+1900,

m=date.getMonth()+1,

d=date.getDate();

return y+"/"+(m<10?"0"+m:m)+"/"+(d<10?"0"+d:d);
}

toYMD(date)==="2016/05/09";

显示地定义转换的逻辑能确保==运算符的强制转换规则,免除不得不查找或记住规则的麻烦。

提示:

  1. 当参数类型不同时,==运算符应用了一套难以理解的隐式强制转换规则。
  2. 使用===运算符,可以避免记住那些强制转换规则,使代码更清晰。
  3. 当比较不同类型的值时,最好显式地进行强制转换,使程序行为更清晰。

[Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符的更多相关文章

  1. [Effective JavaScript 笔记]第57条:使用结构类型设计灵活的接口

    想象创建wiki的库.wiki网站包含用户可以交互式地创建.删除和修改的内容.许多wiki都以简单.基于文本标记语言创建内容为特色.通常,这些标记语言只提供了HTML可用功能的一个子集,但是却有一个更 ...

  2. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  3. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  4. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  5. [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑

    构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...

  6. [Effective JavaScript 笔记]第46条:使用数组而不要使用字典来存储有序集合

    对象属性无序性 js对象是一个无序属性集合. var obj={}; obj.a=10; obj.b=30; 属性a和属性b并没有谁前谁后之说.for...in循环,先输出哪个属性都有可能.获取和设置 ...

  7. [Effective JavaScript 笔记]第45条:使用hasOwnProperty方法以避免原型污染

    之前的43条,44条讨论了属性的枚举,但都没有彻底地解决属性查找中原型污染的问题.看下面关于字典的一些操作 'zhangsan' in dict; dict.zhangsan; dict.zhangs ...

  8. [Effective JavaScript 笔记]第67条:绝不要同步地调用异步的回调函数

    设想有downloadAsync函数的一种变种,它持有一个缓存(实现为一个Dict)来避免多次下载同一个文件.在文件已经被缓存的情况下,立即调用回调函数是最优选择. var cache=new Dic ...

  9. [Effective JavaScript 笔记]第66条:使用计数器来执行并行操作

    第63条建议使用工具函数downloadAllAsync接收一个URL数组并下载所有文件,结果返回一个存储了文件内容的数组,每个URL对应一个字符串.downloadAllAsync并不只有清理嵌套回 ...

随机推荐

  1. Scala学习笔记(五):类和对象

    对象实例的变量组成了对象的内存映射 public是Scala的默认访问级别 Scala里方法参数的一个重要特征是它们都是val,不是var Scala不能定义静态成员 单例对象(singleton o ...

  2. 一个优秀的Android应用从建项目开始

    1.项目结构 现在的MVP模式越来越流行.就默认采用了.如果项目比较小的话: app——Application Activity Fragment Presenter等的顶级父类 config——AP ...

  3. 远程办公《Remote》读书笔记:中国程序员在家上班月入过六万不是梦

    这不是一本新书,这是一本很值得中国程序员看的老书,所以我不是来做卖新书广告的:) 但它的确是一本好书,这本书在Amazon上3个business categories排第一.作者Jason Fried ...

  4. 备忘:SSRS技巧三则

    前言 最近在弄SSRS,发现了三个小技巧.在此记录一下.免得以后忘了. 技巧 1. SSRS输出成EXCEL时,让两个dataset各占一个sheet, 这个简单,在其中一个table的属性加上pag ...

  5. get与post

    1. get是从服务器上获取数据,post是向服务器传送数据.2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.post是通过H ...

  6. 03.C#委托(二章1.1)

    一章1.5-1.8介绍的是com.动态类型及.NET平台一些说明,每个心中都有自己的标准,听一家之言,叫人不爽,相信自己有自己的标准和自己的编程理念就OK了,也不想码那么多说明性的文字,直接跳过吧,当 ...

  7. AngularJS开发指南5:AngularJS表达式详解

    AngularJS表达式类似Javascript的代码片段,通常在数据绑定中用到,写在双大括号中,如:{{表达式}}.表达式是用$parse方法来处理的. 下面是一些合法的AngularJS表达式 1 ...

  8. Day One

    站立式会议 站立式会议内容总结 442 今天完成:学习Android 三种常用的adapter的使用方法,实现主页的可折叠列表 遇到问题:在实现自定义Adapter时,调用出现错误.已解决. 明天计划 ...

  9. 虚拟机去混杂模式与 vlan in vxlan 特性

    1. 去混杂模式 1.1 背景 混杂模式(Promiscuous Mode)是指一台机器能够接收所有经过它的数据流,而不论其目的地址是否是它.是相对于通常模式(又称“非混杂模式”)而言的. 这被网络管 ...

  10. HYSBZ 1269文本编辑器 splay

    比较基本的操作. #include<map> #include<queue> #include<stack> #include<cmath> #incl ...