js的类型转换分为显示类型转换与隐形类型转换,但是只要遇到了类型转换总会满足以下几个要素:
1.toString(任何类型如何转换为字符串)
基本类型转换为字符串
null => "null"undefined => "undefined"true => "true"0 => "0"1.01 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 => 1e+21(当超过21位数字时,转换为指数的表达形式)
以上大家除了数字转换为字符串大家可能不太了解以外,其余的肯定没什么异议,关键是对象如何转换为字符串
复杂类型转换为字符串
当对象转换为字符串时,会调用对象的toString()方法,Object.prototype.toString总会返回内部[[class]](构造函数名称)的属性值,例如大家常见的对象类型判断:
Object.prototype.toString.call(new Object()) === '[object Object]'Object.prototype.toString.call(new Date()) === '[object Date]'Object.prototype.toString.call(new Function()) === '[object Function]'复制代码
但是一些内部对象都对toString()方法进行了重写,例如:
[1,2,3].toString() === '1,2,3'(function(){}).toString() === 'function(){}'new Date().toString() ===' wed Mar 06 2019 23:25:32 GMT+0800 (中国标准时间)'复制代码
我们自己也可以对toString()方法进行重写,例如:
const a = { toString: () => 'toString'}String(a) === 'toString''' + a === 'toString'复制代码
2.toNumber
基本类型转换为数字
true => 1false => 0undefined => NaNnull => 0"" => 0"123" => 123"123xx" => NaN
这里需要注意的一点是,当我们通过Number()与parseInt()进行转换时它们的表现不一样。
其实Number()属于显示类型转换,而parseInt()属于字符串解析,Number()方法转换为数字满足以上规范,而parseInt()则是逐字解析,直到遇到第一个不为数字的字符。parseInt()期望的参数是字符串,若不是,则先隐式转换为字符串(按照以上述式转换)。
复杂类型转换为数字
当复杂类型转换为字符串时,会首先将其转换为基本类型值,然后再按照上述规则转换,在转换过程当中会首先检查是否有valueOf()方法,如果有并且返回的是基本类型的值则按照上述规则转换,如果没有就使用toString()的返回值进行类型转换。例:
Number(new Date()) === new Date().valueOf() //当前时间的时间戳Number({ a:1}) === NaN //对象的valueOf()返回其本身,所以调用toString()返回'[object Object]',按照上述规则,其值为NaNNumber([1]) === 1 //数组valueOf()返回值仍为其本身,所以调用toString()返回'1'Number([1,2]) === NaN //调用toString()返回'1,2'复制代码
3.to Boolean
假值(falsy)
- +0 -0 Nan
- null
- undefined
- false
- ""
除了假值之外的值基本上都是真值,为什么说基本上,因为有一些特殊情况,比如document.all,它是一个类数组对象,至于为什么是假值,这是javascript为了去兼容ie以前的代码,具体原因还是自行搜索吧,没有太大意义。
== 运算符
掌握以上规则之后,接下来就是如何运用了,说到这,那就不得不提 == 运算符了,因为它总是莫名其妙的就相等了。。。在这里我们着重来分析一下。
首先说下它与===的区别, == 允许在相当比较中进行类型转换,而 === 不允许 == 类型转换规则如下
1.字符串与数字之间的相等比较
字符串转换为数字后进行比较,例如:
12 == '12' //'12'转换为复制代码
2.其它类型和布尔类型之间的相等比较
布尔类型会转换为数字进行比较,例如:
ture == 1 //true转换为1true == '1' //true转换为1后,变为 1 == '1',满足第一条规范复制代码
3.对象和非对象之间的相等比较
对象会转为基本类型去比较(转换规则如上所述),例如:
42 == [42] // [42].toString() == '42'复制代码
null和undefined之间的相等比较
null == undefined //true null == false //falsenull == 0 //falsenull == "" //falseundefined == false //falseundefined == 0 //falseundefined == "" //false复制代码
看到这可能就会有人疑惑,0 "" false不都是假值吗,为什么不与null、undefined相等???
em....那我反问一下,如果它们相等,难道不会很奇怪吗???
接下来给大家考验一下大家
"0" == false //???0 == false //???"" == false //???[] == false //???"" == 0 //???"" == [] //???0 == [] //???复制代码