强制类型转换

285 阅读5分钟

值类型转换

将值从一种类型转换为另一种类型称为类型转换,这是显式的情况,隐式的情况被称为强制类型转换,举例!

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,尽量不要使用 ==
  • 尽量使用===来避免不经意的强制类型转换