[Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符
“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";
显示地定义转换的逻辑能确保==运算符的强制转换规则,免除不得不查找或记住规则的麻烦。
提示:
- 当参数类型不同时,==运算符应用了一套难以理解的隐式强制转换规则。
- 使用===运算符,可以避免记住那些强制转换规则,使代码更清晰。
- 当比较不同类型的值时,最好显式地进行强制转换,使程序行为更清晰。
[Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符的更多相关文章
- [Effective JavaScript 笔记]第57条:使用结构类型设计灵活的接口
想象创建wiki的库.wiki网站包含用户可以交互式地创建.删除和修改的内容.许多wiki都以简单.基于文本标记语言创建内容为特色.通常,这些标记语言只提供了HTML可用功能的一个子集,但是却有一个更 ...
- [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑
构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...
- [Effective JavaScript 笔记]第46条:使用数组而不要使用字典来存储有序集合
对象属性无序性 js对象是一个无序属性集合. var obj={}; obj.a=10; obj.b=30; 属性a和属性b并没有谁前谁后之说.for...in循环,先输出哪个属性都有可能.获取和设置 ...
- [Effective JavaScript 笔记]第45条:使用hasOwnProperty方法以避免原型污染
之前的43条,44条讨论了属性的枚举,但都没有彻底地解决属性查找中原型污染的问题.看下面关于字典的一些操作 'zhangsan' in dict; dict.zhangsan; dict.zhangs ...
- [Effective JavaScript 笔记]第67条:绝不要同步地调用异步的回调函数
设想有downloadAsync函数的一种变种,它持有一个缓存(实现为一个Dict)来避免多次下载同一个文件.在文件已经被缓存的情况下,立即调用回调函数是最优选择. var cache=new Dic ...
- [Effective JavaScript 笔记]第66条:使用计数器来执行并行操作
第63条建议使用工具函数downloadAllAsync接收一个URL数组并下载所有文件,结果返回一个存储了文件内容的数组,每个URL对应一个字符串.downloadAllAsync并不只有清理嵌套回 ...
随机推荐
- Sea.js & Require.js
Sea.js 追求简单.自然的代码书写和组织方式,具有以下核心特性: 简单友好的模块定义规范:Sea.js 遵循 CMD 规范,可以像 Node.js 一般书写模块代码. 自然直观的代码组织方式:依赖 ...
- PHP 系列:PHP Web 开发基础
PHP是动态类型的Web开发的脚本语言,PHP以页面文件作为加载和运行的单元,PHP现在有了Composer作为开发包管理. 1.使用Composer管理依赖 自从.NET开发用了Nuget管理程序集 ...
- 几种Boost算法的比较(Discrete AdaBoost, Real AdaBoost, LogitBoost, Gentle Adaboost)
关于boost算法 boost算法是基于PAC学习理论(probably approximately correct)而建立的一套集成学习算法(ensemble learning).其根本思想在于通过 ...
- 端口扫描之王——nmap入门精讲(二)
接着讲上节的内容,上节中提到了一个时间优化的问题是使用参数-n,通过不解析地址来进行优化时间的,但是优化时间的方法还有很多,比如说我们可以通过时间优化(0-5),指定单位时间内的探针数,设置组的大小 ...
- Android图像格式类及图像转换方法
Android图像格式类及图像转换方法介绍 一款软件的开发和图像密切相关,特别是移动应用程序,在视觉效果等方面是至关重要的,因为这直接关系到用户的体验效果.在Android程序开发的过程中,了解存在哪 ...
- Node on Mac 初步
安装node之前 1.之前在windows平台上安装node,直接下载一个安装文件得了.但是mac osx是基于unix架构的嘛,跟linux很像啊. 在linux上安装我们多习惯用命令行工具安装啊, ...
- 转-JS子窗口创建父窗口操作父窗口
Javascript弹出子窗口 可以通过多种方式实现,下面介绍几种方法 (1) 通过window对象的open()方法,open()方法将会产生一个新的window窗口对象 其用法为: window ...
- SQLHelper用到的配置文件格式
格式要牢记 <configuration> <connectionStrings> <add name="dbConnStr" connectionS ...
- CSS布局自适应高度解决方法
这是一个比较典型的三行二列布局,每列高度(事先并不能确定哪列的高度)的相同,是每个设计师追求的目标,按一般的做法,大多采用背景图填充.加JS脚本的方法使列的高度相同,本文要介绍的是采用容器溢出部分隐藏 ...
- 【POJ 1062】昂贵的聘礼(最短路)
Dijkstra最短路,每次限制一个等级差,再更新答案. #include <cstdio> #define N 105 #define INF 1e9 int m, n; int p[N ...