js基础之隐式类型转换

203 阅读6分钟

在未彻底搞清楚js隐式类型转换之前。咱们先看看这几道题: 请说出他们的输出结果:

1 console.log(+true)

2 console.log([]==false)

3 console.log(![]==false)

4 console.log({}==false)

5 console.log({}==false)

6 let res=100+ture+21.2+null+undefined+"sean"+[]+null+9+false

console.log(res)

如果对js的隐式类型转换规则不了解。这6道题很容易就挂掉。

下面我们一步步抽丝剥茧分析下这6道题过程中到底发生了什么:

题目一:

console.log(+true)

对于 + 而言,它比较特殊。一般用作数学运算,但是一旦它的两边任意一边出现了对象或者字符串,那么+就变成了字符串拼接。 观察 coonsole(+true),+右边的true并非字符串也并非对象,所以此时+应该是数学运算。既然是数学运算,此时就需要把true变成数字,true==》数字,最后的结果就是1 ,也就是coonsole(+true)变成了 coonsole(+1)==》输出1

    console.log(+true)
    +true过程:
    (1)true--->Numer  // =1
    (2)+1  -->Number  //1
    

题目二

console.log([]==false) 在两个不同类型数据类型进行==比较时,有这样几个规则:

1 null==undefined:true,但是===结果是false,(因为类型不一样)

2 字符串==对象,需要把对象转换为字符串

3 剩下如果==两边数据类型不一样,都是需要转为数字再进行比较

[]和false数据类型不同,需要两边都转化为数字再进行比较,false---》数字为0,而[]属于对象类型,对象类型转为数字的过程是先转为字符串再转化为数字。而[]===》字符串是空字符串----》数字结果为0。最后结果成了console.log(0==0),所以最后结果是true

    console.log([]==false)过程
    (1) []--->Number   ([])----->String(="")------> Number(=0) (对象类型转为数字的过程是先转为字符串再转化为数字)
        false--->Number  // 0
    (2) console.log(0==0)  (经过第一轮转化两边都是0)
    (3) 结果为true

题目三:

console.log(![]==false) 这题不一样的在于 ![]的优先级要高于==。所以console.log(![]==false)要先进行![]运算,最后再进行==比较。根据上面的规则。![]--->布尔值,[]因为不在0 ,NaN , null ,undefined 和空字符串这五个值中,所以它应该是true,而!ture就变成了false,所以console.log(![]==false)--》变成了console.log(false==false),所以最后的结果还是true

console.log(![]==false)过程
(1) ![]先做运算变成布尔值 , ![]----->Boolean // []先变成true, 再取反成false,
(2) console.log(false==false)  (经过第一步的转化成了)
(3) 结果为true

题目四:

console.log({}==false) 有了上面一道题的基础。这个题就好理解了: {}和false类型不一样。所以他们需要转为数字再进行比较。false--》数字=0;而{}---》数字则需要先调用其toString()转化为字符串再转化为数字,也即是对象--》字符串--》数字,而{}在调用toString方法的时候就有点尴尬了。对象本身的toString()方法是用来判断数据类型的。所以 console.log({}.toString())===>结果成了"[object,object]",那 '[object,object]'----》数字自然就变成了NaN,所以最后结果就成了NaN==0,而我们知道NaN和任何值都不相等。所以最终结果就是false

    console.log({}==false)过程
    (1)  {}----->Number  ({}--- 调用toString()------>Strng (结果是"[object,object]")---调用Number()-- Number('[object,object]')----->Number//结果为NaN
         false--->Number                            // 结果为0
         类型不一样,需要都转化为数字进行比较
    (2)  console.log(NaN==0)                        //结果为false,NaN和任何值都不相等
    (3)  结果为false

题目五

console.log(!{}==false) 同样的道理,因为因为!比==优先级要高,所以!{}要先进行运算。也就是把!{}转化为布尔值,{}不在0,NaN , null ,undefined 和空字符串这五个值中,所以它应该是true,!{}结果是false,等号左边是false,再和右边的false进行比较。结果肯定是true

console.log(!{}==false)过程:
(1) !{}先做运算。 !{}------>Boolean  {}--先转化为---->true,再取反,变成false
(2) console.log(false==false)   //进过上一步转化左右两边变成console.log(false==false)
(3) 结果为true

题目六

let res=100+ture+21.2+null+undefined+"sean"+[]+null+9+false 从左到右开始,100+true,因为+左右变量既没有字符串也没有对象,所以此时+是数学运算。既然是数学运算。肯定需要把左右两边都转化为数字。true-->数字为1,所以100+true=101,同理+21.2=121.2 ,继续+null,把null转为数字为0,还是121.2,继续+undefined(任何数+undefined最终结果都是NaN),所以到这里就成了NaN,再继续+"sean",因为+后面出现了字符串,所以此时结果是"NaNsean",+null后因为此时"NaNsean是字符串,所以变成了字符串拼接,NaNsean+[]=NaNsean,继续往后,因为前面的NaNsean是字符串。所以后面整个都变成了字符串拼接。 最后的结果就成了字符串拼接,NaNseannull9false

100+ture+21.2+null+undefined+"sean"+[]+null+9+false过程
(1) 100+ture=100+1  (+左右两边没有字符串也没有对象,此时+是数学运算)
(2) 100+ture+21.2=121.2  (+左右两边没有字符串也没有对象,此时+是数学运算)
(3) 100+ture+21.2+null=121.2  (+左右两边没有字符串也没有对象,此时+是数学运算)
(4) 100+ture+21.2+null+undefined=NaN (任何数和undefined相加都是NaN)
(5) 100+ture+21.2+null+undefined+"sean"=NaNsean (+右边出现字符串变成字符串拼接)
(6) 100+ture+21.2+null+undefined+"sean"+[]=NaNsean (+左边是字符串所以是字符串拼接)
(7) 100+ture+21.2+null+undefined+"sean"+[]+null=NaNseannull (+左边是字符串所以是字符串拼接)
(8) 100+ture+21.2+null+undefined+"sean"+[]+null+9=NaNseannull9 (+左边是字符串所以是字符串拼接)
(9)100+ture+21.2+null+undefined+"sean"+[]+null+9+false==NaNseannull9false (+左边是字符串所以是字符串拼接)

其他类型转为Number类型:**

1 显示转化:(特定需要转化为Number的)

Number(val),只要出现一个非数字的

ParsetInt、parseFloat()

2 隐式转换

isNaN (val) 数学运算,(特殊情况,+在出现字符串的情况下不是数学运算,是字符串拼接) 在==比较的时候,有些只需要转为数字再进行比较

其他类型转化为字符串的规则

1 显示转化

toString()

String()

2 隐式转化

一般是调用其toString() 加号运算的时候,如果某一边出现字符串则变成字符串拼接

把对象转化为数字,需要先toString()转为字符串再去转为数字

字符串转数字的过程中,只要出现一个非有效数字,全部转化为NaN

其他类型转化为布尔规则

1 基于以下方式可以把其他数据类型转为布尔

 !转为布尔值后取反
 !! 转化为 布尔值类型
 Booleanval

2 隐式转换

只有 0 ,NaN , null ,undefined 和空字符串五个值变成布尔值为false,其他全部是true

** 隐式类型转换规则**

类型一样的几个特殊点:

{}=={} ---false,对象比较的是堆内存的地址

[]==[] ---false

NaN==NaN ---false (nan和任何数据都不相等)

类型不一样的转换规则

1 null==undefined:true,但是===结果是false,(因为类型不一样)

2 字符串==对象,需要把对象转换为字符串

3 剩下如果==两边数据类型不一样,都是需要转为数字再进行比较