JS显性数据类型转换和隐性数据类型转换
一、JS需要类型转换的原因
JS是一种弱类型语言,变量没有类型限制,可以随意赋值。如:
- var a=5;
- console.log(typeof a);//number
- a='我是字符串';
- console.log(typeof a);//string
如上所示,当把数字5赋值给a变量时,a变量的类型是number,当把字符串“我是字符串”赋值给变量a时,a变量的类型是string。
虽然变量没有类型限制,但运算符要求进行运算的变量的类型和运算符期望的类型一致,所以,当不同类型的变量进行加减运算时,就会进行类型转换(如,1+'a'、'3'-'1')。类型转换主要分为两种:强制(显性)类型转换和自动(隐性)类型转换。每种转换又可分为原始类型转换和对象类型转换,原始类型主要包括数字、字符串、布尔值、null、undefined等。
二、强制(显性)类型转换
强制类型转换主要是指通过String、Number和Boolean等构造方法手动转换成对应的字符串、数字和布尔值。
2.1、将其他类型转为字符串
字符串是JS的基本数据类型之一,使用String对象的构造方法可以将任意类型的数据转换为字符串,其中,这里的任意类型主要分为两大类:原始(基本)类型和对象类型。基本类型的转换相对简单,转换方法如下:
基本数据类型 | String类型 |
---|---|
数字 | 对应的数字字符串 |
true | 字符串true |
false | 字符串false |
null | 字符串null |
undefined | 字符串undefined |
如下,均输出对应的字符串值:
- console.log(String(123));//"123"
- console.log(String(true));//"true"
- console.log(String(false));//"false"
- console.log(String(null));//"null"
- console.log(String(undefined));//"undefined"
对象类型的转换稍微复杂些,对象参与基本类型数据运算时,首先是要将对象转换为基本类型。转换方法如下:
1、调用toString()方法,如果返回基本类型的值,则用String()构造方法转换该值。
2、如果toString()方法返回的不是基本类型,则再调用valueOf()方法,如果返回基本类型的值,则用String()构造方法转换该值。
3、如果valueOf()方法返回的也不是基本类型,就抛出错误,如谷歌抛出:Uncaught TypeError: Cannot convert object to primitive value
如下,为了方便查看,重写了String的toString()和valueOf()方法:
例1、当String对象的toString()方法返回基本类型时
- //重写Date对象的toString()
- Date.prototype.toString=function(){
- <span style="white-space:pre"> </span>console.log('执行了toString(),这里返回数字1');
- <span style="white-space:pre"> </span>return 1;
- };
- //重写Date对象的valueOf()方法
- Date.prototype.valueOf=function(){
- <span style="white-space:pre"> </span>console.log('执行了valueOf()方法,这里返回数字2');
- <span style="white-space:pre"> </span>return 2;
- };
- var date=new Date();
- var str=String(date);
输出结果:
- 执行了toString(),这里返回数字1
列2、当toString()方法返回非基本类型时,再次调用valueOf()方法
- //重写Date对象的toString()
- Date.prototype.toString=function(){
- <span style="white-space:pre"> </span>console.log('执行了toString(),这里返回数字1');
- <span style="white-space:pre"> </span>return {};
- };
- //重写Date对象的valueOf()方法
- Date.prototype.valueOf=function(){
- <span style="white-space:pre"> </span>console.log('执行了valueOf()方法,这里返回数字2');
- <span style="white-space:pre"> </span>return 2;
- };
- var date=new Date();
- var str=String(date);//先调用toString()方法,由于返回的不是基本数据类型,再次调用valueOf()方法
输出结果:
- 执行了toString(),这里返回数字1
- 执行了valueOf()方法,这里返回数字2
例3、toString()和valueOf()都返回的不是基本数据类型,则抛出异常
- //重写Date对象的toString()
- Date.prototype.toString=function(){
- <span style="white-space:pre"> </span>console.log('执行了toString(),这里返回数字1');
- <span style="white-space:pre"> </span>return {};
- };
- //重写Date对象的valueOf()方法
- Date.prototype.valueOf=function(){
- <span style="white-space:pre"> </span>console.log('执行了valueOf()方法,这里返回数字2');
- <span style="white-space:pre"> </span>return {};
- };
- var date=new Date();
- var str=String(date);//先调用toString()方法,由于返回的不是基本数据类型,再次调用valueOf()方法,但还是返回非基本数据类型,所以抛出异常
输出结果:
- 执行了toString(),这里返回数字1
- 执行了valueOf()方法,这里返回数字2
- Uncaught TypeError: Cannot convert object to primitive value
也可以采用如下方式验证:
- var obj={
- valueOf:function(){
- console.log('执行了valueOf()方法,这里返回数字2');
- return 2;
- },
- toString:function(){
- console.log('执行了toString(),这里返回对象');
- return 1;
- }
- };
- String(obj);
2.2、将其他类型转换成数字
使用Number构造函数转化任意类型的值时,也分为两种:一种是将基本类型的值转换成数字,一种是将对象型的值转换为数字。基本类型的数据转换数字的规则如下:
基本数据类型 | 数字类型 |
---|---|
数字字符串 | 对应的数字 |
true | 1 |
false | 0 |
null | 0 |
undefined | NaN |
空字符串 | 0 |
不可完全被解析为数值的字符串 | NaN |
如下:
- console.log(Number(123));//123
- console.log(Number('123'));//123
- console.log(Number('123a'));//NaN
- console.log(Number(''));//0
- console.log(Number(true));//1
- console.log(Number(false));//0
- console.log(Number(undefined));//NaN
- console.log(Number(null));//0
- console.log(Number(' \t\n 3.23322\t '));//Number可以自动去掉两头空白符,输出3.23322
注:Number构造函数将字符串转换为数字时,字符串必须完全被为数字,即只要有一个字符无法转为数值,则整个字符串都会被转为NaN。如果想不精确转换,可以使用parseInt()函数,parseInt()函数将最大限度的将字符串转换为数字。如:
- console.log(parseInt('123abc456'));//123
- console.log(Number('123abc456'));//NaN
对象类型转换为数字,和上面对象转换为字符串类似,只是转为数字时是先调用valueOf()方法,再调用tostring()方法:
1、首先调用对象自身的valueOf()方法,如果返回基本类型的值,则用Number构造函数进行转换。
2、如果valueOf()返回的不是基本类型的值,则再调用toString()方法,如果返回基本类型的值,值用Number构造函数进行转换。
3、如果toString()返回的不是基本类型的值,则抛出异常。
验证方法与上面转为字符串的类似,如:
- var obj={
- valueOf:function(){
- console.log('执行了valueOf()方法,这里返回数字2');
- return 2;
- },
- toString:function(){
- console.log('执行了toString(),这里返回对象');
- return 1;
- }
- };
- Number(obj);
输出结果:
- 执行了valueOf()方法,这里返回数字2
2.3、将其他类型转换为布尔值
使用Boolean构造函数转换其他类型的数值时,除了下面几种情况返回false外,其他的值都返回true。
1、null
2、0、-0或者+0
3、NaN
4、'' 空字符串
5、undefined
如:
- console.log(Boolean(null));//false
- console.log(Boolean(0));//false
- console.log(Boolean(-0));//false
- console.log(Boolean(+0));//false
- console.log(Boolean(''));//false
- console.log(Boolean(NaN));//false
- console.log(Boolean(undefined));//false
- console.log(Boolean({}));//true
- console.log(Boolean([]));//true
- console.log(Boolean("蝈蝈"));//true
- console.log(Boolean(new Boolean(false)));//true
三、自动(隐性)类型转换
自动类型转换就是不需要人为强制的进行转换,js会自动将类型转换为需要的类型,所以该转换操作用户是感觉不到的,因此又称为隐性类型转换。自动类型转换实际上和强制类型转换一样,也是通过String()、Number()、Boolean()等构造函数进行转换,只是该操作是JS自己自动完成的而已。自动类型转换的规则和强制类型转换的规则一致,所以这里不再进行描述。下面列举几个例子:
3.1、转换为数字
在所有加减乘除等需要数字类型的地方,JS会自动使用Number构造函数对变量进行转换。
- console.log('1'-'2');//-1
- console.log(1+'2');//12 加号+比较特殊,其他类型和字符串相加都会转换成字符串
- console.log('1'-true);//0
- console.log('1'*{});//NaN
- console.log('1'-'a');//NaN
3.2、转换为字符串
字符串自动转换主要表现为字符串的拼接,字符串和其他类型用加号(+)拼接时,其他类型都自动转换为字符串。
- console.log('1'+'2');//12
- console.log('1'+'a');//1a
- console.log('1'+1);//11
- console.log('a'+null);//anull
- console.log('1'+undefined);//1undefined
- console.log('a'+{});//a[object Object]
- console.log('a'+true);//atrue
3.3、转换为布尔值
当在任意需要布尔类型的地方(如,if条件出、三元运算符条件等),系统都会自动调用Boolean()构造函数将值转换为Boolean类型。null、0、-0、+0、'' 空字符串、undefined、NaN这些都会转换为false,其他的值都会转换为true。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步