值类型转换
将值从一种类型转换为另一种类型称为类型转换,这是显式的情况,隐式的情况被称为强制类型转换,举例!
var a = 42;
var b = a + ""; // 隐式强制类型转换
var c = String(a); // 显式强制类型转换
抽象值操作
string字符串数据类型转换
1.使用:[val].toString()
null和undefined是禁止使用toString的(保护机制),会报错
数组:[]=>"" ; [12]=>"12";
普通对象.toString()的结果是"[object Object]"
2.使用:String(...)函数
如果有toString()方法,则调用该方法并返回结果
如果是null,返回”null”,如果是undefined,返回”undefined”
number数据类型转换
使用:Number()
字符串转换为数字:
只要字符串中包含任意一个非有效数字字符(第一个点除外,表示小数点)结果都是NaN,空字符串会变为0
布尔类型转换为数字:
true=>1,false=>0
null=>0
undefined=>NaN
引用数据类型转换为数字:
会先把它基于toString()方法转换为字符串,然后再转换为数字
对象:{}/{xxx:'xxx'}.toString()=>"[object Object]"=>NaN
数组:[]=>''=>0; [1]=>'1'=>1; [1,2]=>NaN(因为逗号为非有效数字字符)
parseInt()/parseFloat()主要应对字符串来使用,也是转化数字的方法,对于字符串来说,它是从左到右依次查找有效数字字符,直到遇到非有效数字字符(此时就不再往后找了),就把已经找到的当做数字返回,如果没有有效数字字符,则返回NaN
NaN(not a number的缩写)
不是一个数字,但是它属于数字类型,不和任何值相等,包括自己,NaN和任何数数学运算结果都是NaN
isNaN():用于检测一个值是否为有效数字,如果不是,返回true,如果是,返回false。
在使用isNaN进行检测时,它会先验证检测的值是否为数字类型,如果不是,则先基于Number()这个方法,把值转为数字类型,再验证isNaN(NaN)=>true
boolean布尔数据类型转换
只有0,NaN,"",null,undefined五个值转化为false,其余都转为true
使用:Boolean([val])
隐式类型转换的方式有:
!/!!
!先转布尔,再取反
!!取反再取反,实质上就是转换为布尔
条件判断 if(){}
nul/undefined转换
null:“意料之中”(一开始不知道,手动先设置为null,之后会赋值),一般用null作为初始的空值,因为0不是空值,它在栈内存中占有空间
undefined:“意料之外”(创建变量没有赋值,默认值就是undefined)
字符串和数字之间的显式转换
通过String()和Number()来实现,String()遵循ToString规则,将值转换为字符串基本类型,Number()遵循ToNumber规则,将值转换为数字基本类型
显式解析数字字符串
解析字符串中的数字和转换为数字返回结果都是数字,但解析和转换两者之间有明显差别,举例!
var a = "42"
var b = "42px"
Number(a) // 42
parseInt(a) // 42
Number(b) // NaN
parseInt(b) //42
解析允许字符串中出现非数字字符,因为解析从左到右,遇到非数字字符则停止并返回已拿到的数字,而转换遇到非数字字符则返回NaN,各有各的用途
字符串和数字之间隐式强制类型转换
从数字转字符串,使用+""
,+
号的其中一个操作数是字符串,则执行字符串拼接,否则执行数字加法
从字符串转数字,使用-0
,-0
的操作为了执行减法运算,会先把操作数先转换为字符串(toString()),再转换为数字
“==”和“===”
常见误区:“==检查值是否相等,===检查值和类型是否相等”
这种说法是错误的,正确的解释是:“==允许在相等比较中进行强制类型转换,===不允许”,举例!
var a = "42";
var b = true;
a == b // false
为什么“42”转boolean明明是true,这里比较后却返回false?其实这是一个坑,这里其实并不会发生ToBoolean转换,而是把布尔值true转换成了数字1,字符串“42”转换成了数字42,这样一比较,自然返回false,很怪对吧,==的转换规则是这样的:
如果Type(x)是布尔类型,则返回ToNumber(x)==y
如果Type(y)是布尔类型,则返回x==ToNumber(y)
所以上面的例子即使反过来,结果也是一样的
因此这里推荐,在任何情况下都不要使用==进行判断,举例!
if(a == true) // 这样用条件不成立会出错
if(a === true) // 这样用条件不成立会出错
if(a) // 这样用可以
if(!!a) // 这样用更好
if(Boolean(a)) //这样用可以
值得注意的是null和undefined使用==结果为true,因为undefined是由null衍生而来的
对象和非对象之间的比较
如果Type(x)是字符串或者数字,Type(y)是对象,则返回x==ToPrimitive(y)
如果Type(x)是对象,Type(y)是字符串或者数字,则返回ToPrimitive(x)==y
这里只提到字符串和数字,因为布尔值会被强制类型转换为数字
ToPrimitive()
方法会先检查该值是否有valueOf()方法,有就返回基本类型值,并使用该值进行强制类型转换,没有就使用toString方法的返回值进行强制类型转换
安全的运用隐式强制类型转换
- 如果两边值中有布尔值,不要使用
==
! - 如果两边值中有 [],"",0,尽量不要使用
==
- 尽量使用===来避免不经意的强制类型转换