Js类型转换之相等运算符[初级]

(注:此篇博客主要讨论相等运算符的类型转换)

发现问题

几天前在审查公司实习生代码时查出一个bug,代码是这样写的:3d


                                                               pic1cdn

他这里的业务是先从接口中拿到某个对象的数据,若是这个对象为空的话会将它赋值为null,
若是对象有值作进一步处理,若是对象的str属性不为空再作某些处理。

固然,这里作if判断的话彻底没有必要利用相等操做符, 直接经过数据自己判断就能够了即 对象


可是最开始的时候我只是以为他的代码不够规范,不以为他的写法(pic1)有什么逻辑上的影响,后来才发现这两种写法有着天差地别。pic1中的两个if判断都会永远返回false。blog

案例解析

首先咱们如今控制台打几个简单的语句继承


咱们能够得出:接口

(结论1)将全部对象包括空对象转成布尔值都会返回true(不包括null)。ip

(结论2)咱们都知道if语句条件判断的括号中能够放变量,也能够放表达式。字符串

  • 若是括号中是变量的话,则直接将其转换为布尔值。
  • 若是括号中是表达式,则先将表达式运算出结果后再将结果取布尔值。

因此针对两个案例中的第一个if判断咱们能够模拟出get


很明显,第一个判断返回值为true,第二个if判断返回值是false,原型

咱们来分析一下上边这段代码,

首先第一个判断至关于Boolean(o),根据结论1,这个返回值必定是true。

第二个判断会先计算o==true的结果,而后再将其转换为布尔值,可能有少部分同窗也会想固然的觉得这里会先将o转换为布尔值,和等号右边的类型相同后再做比较,

咱们能够在控制台打一下这个表达式:


若是是先将o转成布尔值后再与true作比较的话,返回值必定为true即:


可见他不是这样转换的,那么它是怎样转换的呢? 

我去查了一下红宝书,是这样规定的:

在执行相等运算符时,若是有一方类型为布尔值,那么会将布尔值转换为数字类型后再比较

那在咱们这个例子中布尔值true被转换成1,那等号另外一端的对象是怎样转换的呢?因而我往下翻,还有这样一条:

若是有一方为对象,另外一方为非对象,则执行对象的valueOf方法后获得基本数据类型再做比较,若是得不到基本数据类型,再执行它得toString方法后进行比较。

那咱们先看一下咱们实例化的对象o继承Object原型上默认定义的valueOf方法和toString()方法会返回什么


因此咱们能够猜测o==true判断时经历了如下几个步骤:

  1. 执行o的valueOf方法,返回对象自己
  2. valueOf的返回值不是基本数据类型,执行它的toString方法,返回字符串"[Object Object]"
  3. 将true转换为数据类型,返回1
  4. 将 "[Object Object]" 转换为Number类型,返回NaN
  5. 判断 NaN 是否全等于 1
  6. 返回false

为了验证咱们上边的猜测,我在控制台写了如下代码:


足以证实咱们的猜测步骤是正确的。

然而咱们案例中的第二个判断字符串与布尔值比较也是将其先转换成数值后再进行比较。

至关于:Number(o.str) === Number(true)

前者返回NaN,后者返回1,固然不等。

类型扩展

咱们上面的案例是解决了,可是其余类型的相等运算符是怎样转换的呢?

我先提出两个问题 

1.你们都知道 null==undefined 返回的结果为true,那么它是怎样进行类型转换的呢?

2.null==0 undefined==0的返回值分别是多少?

不卖关子,直接说答案

第一个问题

不会进行类型转换

误区:有的同窗可能觉得null和undefined都会先转换为布尔值,而后再判断相等性。

正确思路:其实他们的相等是js规定的,这里不会进行类型转换。

第二个问题

返回值都为false

误区:若是按照案例中的思路有些人可能会觉得null和undefined也是都会被转换为Number后再作判断。

对undefined来说Number(undefined)返回值为NaN,与0相比返回false很正常,

可是Number(null)的返回值为0 为何也与0相比返回false呢?

正确思路:其实这里js规定Null和undefined与其余数据类型比较时不会进行类型转换,因此返回结果都为false。

更多类型的相等运算符比较:


来自MDN

相关文章
相关标签/搜索