JS基础知识总结——数据类型转换(强制类型转换)

关于什么是基础数据类型和复杂数据类型,请看上一节
先说一下强制类型转换,

基础数据类型(原始数据类型)→基础数据类型的转换:
①基础数据类型→字符串

任何基础数据类型转为字符串的结果都是在原来基础上加一个引号。
看下面的例子
 
1
2
3
4
5
6
 
 
 
alert(String(undefined));    //undefined 到字符串
alert(String(null));    //null到字符串
alert(String(true) );    //布尔类型到字符串
alert(String(555));    //数字类型到字符串
alert(String("STRING"));    //字符串到字符串
 
 
 
Tip:将任何数据转换为字符串最简单的办法就是 让它与空字符进行加法运算
所有上面的代码也可以这么写:
 
1
2
3
4
5
6
 
 
 
alert('' + undefined);    //undefined 到字符串
alert("" + null);    //null到字符串
alert("" + true);    //布尔类型到字符串
alert("" + 555);    //数字类型到字符串
alert("" + "STRING");    //字符串到字符串
 
 
 


②基础数据类型→数字

这里要区别对待:
undefined:转化为数字为NaN
null:转化为数字为0
布尔类型:true→1;false→0
字符串:如果字符串本身代表数字则直接转换为对应的数字;如果不是则转换为NaN
 
1
2
3
4
5
6
 
 
 
alert(Number(undefined))    //undefined转换数字
alert(Number(null))    //null转换数字
alert(Number(true))    //布尔类型
alert(Number(false))    //布尔类型
alert(Number('123'))    //字符串
alert(Number('a123'))    //字符串
 
 

Tip:将任何数据转换为数字的最简单办法就是 对它进行“一元加”运算
所有上面的代码也可以这么写:
 
1
2
3
4
5
6
 
 
 
alert(Number(undefined))    //undefined转换数字
alert(+null)    //null转换数字
alert(+true)    //布尔类型
alert(+false)    //布尔类型
alert(+'123')    //字符串
alert(+'a123')    //字符串
 
 

Tip:将字符串转化为数字时,会自动过滤一个字符串前导和后缀的空格和转义字符。
所以,想想如下代码的结果是什么?
 
1
 
 
 
+'\t\v\r12.34\n '
 
 



③基础数据类型→布尔类型

只有六个数据转化为布尔类型为false:
①0
②-0
③undefined
④null
⑤NaN
⑥""
 
1
 
 
 
console.log(Boolean(0),Boolean(-0),Boolean(undefined),Boolean(null),Boolean(NaN),Boolean(""))
 
 

Tip:将任何数据转换为布尔类型的最简单办法就是 进行两次取反(这种说法也许不太严谨)
所有上面的代码也可以这么写:
 
1
 
 
 
console.log(!!0,!!-0,!!undefined,!!null,!!NaN,!!"")
 
 


复杂数据类型(对象)→基础数据类型的转换:
①对象→数字类型

对象的转换规则比较复杂。
①先调用对象自身的valueOf方法,如果该方法返回原始类型的值(数值、字符串和布尔值),则直接对该值使用Number方法,不再进行后续步骤。
②如果valueOf方法返回复杂类型的值,再调用对象自身的toString方法,如果toString方法返回原始类型的值,则对该值使用Number方法,不再进行后续步骤。
③如果toString方法返回的是复合类型的值,则报错。
所以如果出现下面的表达式时,根据上面的规则总结后变为:
 
1
 
 
 
Number({name:123})
 
 

内部运算的实际流程是下面的样子:
 
1
2
3
4
5
 
 
 
if (typeof {name:123}.valueOf() === 'object'){
    Number({name:123}.toString());
} else {
    Number({name:123}.valueOf());
}
 
 

上面代码的valueOf方法返回对象本身({name:123}),所以对toString方法的返回值“[object Object]”使用Number方法,得到NaN。

为了进一步论证上面的转换规则,下面的三个例子即可:
 
1
2
3
4
5
6
7
8
9
10
11
 
 
 
//1由于valueOf返回的是原始类型,所有直接对valueOf的返回值进行Number运算并返回,结果为123
Number({valueOf:function (){return "123";},toString:function(){return 888;}})
 
//2由于valueOf返回的是复杂类型,所以再次调用对象自身的toString方法;
//又由于该对象的toString方法返回的是原始数据类型,所以对toString的返回值进行Number运算,并返回
//所以最终结果为888
Number({valueOf:function (){return {name:123};},toString:function(){return 888;}})
 
//3由于valueOf和toString返回的都是复杂类型,所以最终报错
//Uncaught TypeError: Cannot convert object to primitive value
Number({valueOf:function (){return {name:123};},toString:function(){return {name:888};}})
 
 


②对象→字符串

与上面“对象→数字”的类似,只是toString和valueOf方法的调用顺序不同,规则如下:
①先调用toString方法,如果toString方法返回的是原始类型的值,则对该值使用String方法,不再进行以下步骤。
②如果toString方法返回的是复合类型的值,再调用valueOf方法,如果valueOf方法返回的是原始类型的值,则对该值使用String方法,不再进行以下步骤。
③如果valueOf方法返回的是复合类型的值,则报错。
所以如果出现下面的表达式时,根据上面的规则总结后变为:
 
1
 
 
 
console.log(String({name:123}))
 
 


还是举三个例子来验证上面的规则:
 
1
2
3
4
5
6
7
8
9
10
11
12
 
 
 
//1 由于toString方法返回值为原始数据类型,所以直接对toString的返回值进行String运算并返回
//所以结果为"123"
String({toString:function(){return 123},valueOf:function(){return 888}})
 
//2 由于toString方法返回值为复杂类型,所以再次调用了该对象的valueOf方法,
//valueOf方法的返回值为原始类型,所以就对该值进行了String运算并返回
//所以结果为"888"
String({toString:function(){return {name:123}},valueOf:function(){return 888}})
 
//3 由于toString和valueOf的返回值都不是原始数据类型,所以直接报错了
//Uncaught TypeError: Cannot convert object to primitive value
String({toString:function(){return {name:123}},valueOf:function(){return {name:888}}})
 
 


②对象→布尔型

这个最好记,所有对象转换为布尔类型的结果都是true,即使是false对应的布尔对象也是true。
 
1
 
 
 
console.log(Boolean(new Boolean(false)))
 
 



基础数据类型→复杂数据类型的转换:
转换方法很简单,就是利用Object方法,这点和上面的几种方法一样(如强制转换为字符串时,使用String方法)。
①undefined和null →对象

其中undefined和null是不能转化为Object的,当使用Object方法对undefined和null进行转换时会报错,但是现在新的浏览器上已经解决了这个问题,会返回一个
 
1
 
 
 
console.log(Object(undefined), Object(null))
 
 


②数字和布尔类型→对象

数字和布尔类型的转换类似,转换后返回一个对象,里面只有一个原始值,就是他原来本身。
 
1
 
 
 
console.log(Object(123), Object(true))
 
 


③字符串→对象

当对字符串进行转换时,与数字和布尔类型稍微不一样,转换后的结果会对每一个字符创建一个独立的索引,从0开始一直排下去,
每个索引对应的值就是他第n个位置上的字符;在此基础上,还有一个length属性。
 
1
 
 
 
console.log(Object("abcd"))
 
 

Tip:当你访问一个字符串的length属性时,其实浏览器是将该字符串临时转换为Object,然后再返回转换结果的length属性。所以你会经常看到如下的面试题
 
1
2
3
4
5
 
 
 
var str = "123456"
alert(str.length)    //此时为6
str.length = 5;
alert(str.length)    //此时仍然为6,因为每次对一个字符串使用"."时,
//都是临时转换为一个Object,你对字符串的length值进行修改,只是改一个临时的Object,不会对原字符串有任何印象
 
 



参考链接:
http://www.css88.com/archives/5199
推荐音频教程:
沙老师的第10期基础知识总结(喜马拉雅)

posted @ 2017-01-10 17:33  天涯海角路  阅读(284)  评论(0)    收藏  举报