本文从转换为string类型、转换为number类型、转换为boolean类型三个大类总结JavaScript数据类型转换
前置方法:ToPrimitive
1. 引用类型转字符串的方法:ToPrimitive,调用该对象的valueOf函数求原始值,如果结果是引用类型再执行toString。
var a = {}
var b = {name: '张三'}
[1,2].valueOf() // [1,2]
[1,2].valueOf().toString() // '1,2'
[].valueOf().toString() // ''
a.valueOf().toString() // ''a.valueOf().toString()
b.valueOf() // {name: '张三'}
b.valueOf().toString() // '[object Object]'
2. 引用类型在转数字的时候先用上述方法转为字符串,再转数字
这里就有一个常见的面试坑题,如下如果打印结果为1,求a。
if(a==1 && a==2){ console.log(1) }
解题思路,如果a==1 && a==2成立,则a不可能为值类型,只可能是引用类型,在引用类型转换为数字时,会先调用valueOf方法求原始值,那么改写一下valueOf方法就做到了
var a = {
i:0,
valueOf:function(){
return ++a.i
}
}
第一大类:转换为string类型
1. +字符串连接符,string>number>boolean,即:+两边有字符串或引用类型都转为字符串,
1+'1' // '11', //有字符串
[1,2]+1 // '1,21' // 有引用类型[1,2]转为[1,2].valueOf().toString()为'1,2'
第二大类:转换为number类型
一、数学计算,+、-、*、/、%
1. + 在****两边没有字符串或引用类型情况下转为数字
1+1 // 2 //没有字符串直接转数字计算
false + 1 //1 //没有字符串,false转为数字0
2. -、*、/、% 直接转换成数字,然后计算
1-'1' // 0
true-1 // 0
二、关系运算符>、<、==、!= ,运算符两边先转为数字后再计算,这里以 == 为例
- 两者如果是表达式,先计算表达式再比较
- 两者中如果有一个是引用类型,则该引用类型执行ToPrimitive后再进行比较
- 两者都是值类型,判断类型是否相同,不同则转数字(执行Number(x))之后再比较
- 特殊情况,两者如果有一个是null和undefined,则只有null或者undefined == null和undefined为true,其余为false
- ToPrimitive:执行该对象的valueOf函数,如果结果是引用类型再执行toString
举例说明
-
[]==![],右边![]是表达式,先计算![]值为false再进行下一步比较:[]==false
-
[]==false,有一个是引用类型,需要执行ToPrimitive:[].valueOf()返回[],[].toString()返回空字符串'',再进行下一步比较'' == false
-
'' == false,两者都是值类型,则执行转数字:Number('') // 0,Number(false) // 0,转化为比较 0 == 0 // true
-
特殊情况,两者如果有一个是null和undefined,JavaScript规范中规定,比较相等之前不能将null和undefined转换成其他任何值,并且规定null == undefined。解读一下就是****null 和 undefined 除了这两个之外,和谁比较等性结果都是false.
// 掘金bug了,这个代码块展示成了文字
undefined == null // true
undefined == '' // false
undefined == 0 // false
undefined == true // false
undefined == false // false
所以在代码里常见人这么写 if(res == undefined || res == null){},这其实是js基础不扎实的表现,这么写其实等价于 if(res == null){}
注意:单个字符串比较unicode编码 (始终遵循A<Z<a<b)
第三大类:转换为boolean类型
1. if(x){}和!x,这两种情况会转换为boolean值
非boolean值类型转boolean值,有值为true,无值为false,0和''被认为没有值
!1 // false
!0 // true
!'' // true
!NaN // true
!undefined // true
!null // true
引用类型转****boolean值,全为true,因为地址始终存在,有地址被认为有值
!{} // false
![] // false
码字不易,帮忙点个赞!!!