Fork me on GitHub

空数组返回true引发的血案

    之前做项目的时候,总会处理各式各样的数据,来进行绘图。但是当后台返回一个空数组的时候,页面中并不会显示没有数据的图。代码如下:

1
2
var arr = []
if(arr){console.log(124)}else{console.log('无数据')}

我明明判断了,怎么会不显示呢?下面我们就来看看,具体是怎么回事。

‘==’ 和 ‘===’

    比较大小,只有数字能进行比较,所以所有比较类型最终都会转为数字进行。非全等(==)的情况下,只要值相同就返回True。而全等(===)的时候需要值和类型都要匹配才能返回True。即在非全等的情况下,要进行类型转换。全等条件下则不进行类型转换。

  1. 非全等条件下

    • 若两个操作数类型相同,若值不相等,则不相等。反则相等。
    • 若两个操作数类型不同,若检测相等,则需要遵循以下规则
      1) 若一个值为null,另一个为undefined,则他们相等
      2) 若一个值为数字,另一个是字符串,则会先将字符串转换为数字,然后使用转后的值进行比较
      3) 若其中一个值为true,则将其转换为1再进行比较。若其中一个为false,则转为0再进行比较
      4) 若一个值是对象,另一个值是数字或字符串,则会使用valueOf(),再尝试使用toString(),除了日期类,日期类只使用toString()转换(注:后面会细说,先记住这些规则)
      5) 其他不同类型之间的比较均不相等。
      1
      2
      3
      4
      5
      6
      7
      {'a': 1} == {'a': 2} // false
      1 == 1 //true
      null == undefined // true
      true == 1 //true
      false == 0 // true
      ({}) == 0 // false 解释: ({}).valueOf 返回其本身 Object {},则然后进行toString()转换"[object Object]",则转换为数字为NaN,所以{}!=0同时{}!=1
      [] == true // false 解释: [].valueOf 返回其本身 [],则然后进行toString()转换"" 则其转换为数字0
  2. 全等条件下

    • 若两个值类型不相同,则他们不相等
    • 若两个值都是null或者undefined,则他们相等
    • 若两个值都是true或都是false,则他们相等
    • 若其中一个值是NaN,或者两个值都是NaN,则他们不相等。NaN和其他任何值都不相等,包括其本身! 通过x!==x来判断NaN,只有在x为NaN的时候,这个表达式的值才为true。
    • 若两个是数字且数值相等,则他们相等。如果一个为0,另一个为-0,则他们同样相等
    • 若两个值为字符串,且所含的对应位上的数值也完全相等。则他们相等
    • 若两个引用值指向同一个对象、数组或函数,则他们是相等的。若指向不同的对象,则他们不等,即便两个对象具有完全一样的属性
      1
      例子就不一一列举了

类型转换

    类型转换如下:
avatar

** 注:基本类型(原始类型值): String、Number、Boolean、undefined、null、Symbol(es6)
对于类型转换,我们需要记住如下几个转换。undefined、null、0、-0、NaN、’’都将转为false。所有其他值,包括所有对象(数组)都会转为true。那么按照这么来说,[] == true应该返回true啊?为什么是false呢?因为在执行相等判断的时候都转化为了数字,这两个值是不相等。但是在if([]){console.log(1)}这个判断的情况下,则会很神奇的发现打印出来了1,说明[]此时为true,为什么呢?因为这里执行了一个对象到布尔值的转换故返回true。(注:这里可以理解为对象转为布尔值和对象转换为数字的差异)

上面说了对象转化为布尔值,这里再细说一下对象转换为字符串和对象转换为字符串

  • 对象转换为字符串

a、如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,js将这个值转换为字符串(若本身不是字符串),并返回这个字符串结果。

1
({a:1}).toString() ----> "[object Object]"

b、若对象没有toString()方法,或者这个方法返回的不是一个原始类型值,那么js就会调用valueOf()。如果存在这个方法,则js调用它。若返回值是原始类型值,js将这个值转换为字符串,并返回这个结果。
c、若js无法从toString()或valueOf()获得一个原始值,则将抛出一个类型错误异常

  • 对象转换为数字
    a、对象转换为数字和对象转换为字符串做的事一样,但是它会先尝试使用valueOf()
    b、若对象有valueOf(),则返回一个原始值,然后js将其转换为数字返回。否则,若有toString()方法,返回原始值,然后js将其转换为数字返回。若两者都没有,则抛出一个类型错误异常
    1
    [] == 0 //true 释义:数组继承了默认的valueOf()方法,这个方法返回一个对象而不是一个原始类型值,因此,数组到数字的转换则调用toString()方法。空数组转换为空字符串,空字符串转为数字0

案例

看完上面的解释,分析一下下面的例子

1
2
3
4
5
6
7
8
9
({}) == ({}) // false
[] == ![] // true
[] == [] // false
![] == true // false
'' == '0' // false
'' == 0 // true
false == 'false' // false
false == undefined // false
false == null // false

其中某个问题的解释会牵扯到运算符优先级的问题。参考地址:
[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence]

坚持原创技术分享,您的支持将鼓励我继续创作!