类型转换!!!JS中的类型转换

说明

本文是经过多次的补充和修改的,一部分来自小编的自我总结,另一部分来自于读书时遇到的相关笔记与心得。一开始仅仅作为小编的工具文,但是理解会不断的更新,所以小编的文章基本上都会持续的进行自我质疑、挑战和更新。本文有参考《你不知道的js 中卷》第一部分第四章的内容。也算是一个读书笔记呢。

写在前面

类型转换分为两种,一种是显式类型转换,另一种是隐式类型转换,也称为强制类型转换。

隐式类型转换就是在不知不觉中进行了转换,(隐蔽的类型转换),其副作用也不明显,而非代码层面的转换。

上例子:

a = 11;
//隐式类型转换
var b = a + '';

//显式类型转换(强质类型转换)
var c = String(a)

//这两个还有细微的区别。
a+''; //调用valueOf 再转成字符串,调用toString
String(a)//直接调用toString转成字符串
//因此我们在定制这两个方法是应该格外小心。如果是对象可能不同。

但是还要注意的一点是,js中有时也没有区分的这么详细,就统一成为强制类型转换。

本文中为了区分的更细致,将其分为两种(隐式和显式)

转换为数字

方法一:Number()

这是一个转型函数,实例如下:

var m;
Number(m);

参数m分为六种情况,数字、布尔、字符串、对象、null、undefined。

  • 当参数时数字时,不论是几进制数字,都转换成十进制返回。
  • 当参数时布尔值时,true返回1,false返回0.
  • 当参数为字符串时,若字符串的内容是数字时,转换成十进制返回。如果是空字符串或者部分非打印的转义字符如\n、\r等返回0,其他返回NaN,必须是严格的数字,"12px"返回NaN。
  • 当参数为对象时,先对对象执行toprimitive()抽象操作,变为基础类型的值再按照前面的规则进行转换。该方法的操作流程是,先对它执行valueOf方法,若果没有返回基本类型的值,就调用toString方法,再返回它的值。如果valueOf和toString没有返回基本类型的值,报错TypeError。从es5开始,使用Object.create(null)创建对象的[[prototype]]属性为null,没有valueOf和toString函数,因此无法进行强制类型转换。
  • 当参数是null,返回0.
  • 当参数是undefined,返回NaN。

来一点补充:~运算符(字位操作‘非’)中其实也涉及了强制类型转换,先执行了Number的逻辑,再转换成32位即toInt32的抽象操作。

严格来说不算强制类型转换,但是也涉及了类型转换逻辑。

方法二:parseInt()

该方法用于字符串转数字,也是一个转型函数。只针对字符串,传其他的没有用!!也会转成字符串!!

如果说Number是严格的数字转换,那parseInt就是非严格的数字解析。

他有两个参数,第一个是要解析的字符串,如果不是字符串自动转换成字符串。第二个是数字在解析时用到的进制,在2-36之间。

paseInt("1010"2);       //10
paseInt("0xa");           //10 ,
//注意:ES5之前函数本身有判断基数的机制。注意如果第一位是0 ,转成八进制了!!!不是十进制!!!
//如08分,返回0,因为八进制没有8!可以将参数设置为10 来解决。但是ES5之后就默认转换为十进制。
parseInt("+10");          //10
parseInt("01.25");        //1   忽略前导0  
parseInt("");             //NaN
parseInt("12px")     //12

//一个特殊的例子:
parseInt(1/0,19)  //18
//解析:
//首先将1/0转成字符串,即“infinity”再进行数字解析。
//以19为基数,合法的字符有:0~9,a~i
//所以第二个字符n为不合法字符,就像12Px一样的,会直接种植解析
//因此等价于parseInt("i",19) //18

//还有一些看起来奇怪但是可以解释的通的例子:
parseInt(0.000008)  //0   等价于 parseInt('0.000008') 
parseInt(0.0000008//8  parseInt('8e-7')
parseInt(false,16)  // 250 等价于 parseInt('false',16)又等价于parseInt('fa',16)最后转成十进制15*16+10*1 = 250
parseInt(parseInt,16)  //15 等价于 parseInt('function ......',16)又等价于parseInt('f',16)15*1 = 15
parseInt(103,2)    //2  等价于parseInt('10',2)

第一个字符不是数字或者正负号就直接返回NaN,字符串从前往后解析,既不是数字也不是基数中的字符就停止解析。

parseInt函数是非常靠谱的,只要使用得当就不会有问题。

方法三:parseFloat()

该方法也是一个转型函数,与parseInt的解析机制大致相同。

有一点不同,第一个小数被认为是浮点数的一部分,第二个小数点无效。可以识别科学记数法。

方法四:加减号一元运算符

加号运算符:

  1. 若存在对象,先转换成基础值。
  2. 若存在字符串,则进行字符串的拼接工作。
  3. 若没有字符串,先用Number转成数字进行加法运算。
    注意:一元加运算符还有一个常见功能,将日期类型专为数字,返回一个时间戳数字。

因此也可以这样用var timeStamp = +new Date(),但其实日期类型已经提供了相关的方法,也大可不必这样写,不推荐哈。

减号运算符:
与加号运算符一样,除此之外还可以反转符号,正数变负数,负数变正数。

-'3.14'//-3.14
- -'3.14'//3.14 注意两个减号之间需要有空格哦,否则就当作了前减减运算符啦

//一个头晕的一个例子
1 + - + + + - + 1//2  


看到上边头疼的例子,告诫大家,不要把一元运算符与其他运算符当在一起使用,容易混淆。d = +cd += c天壤之别啊!

方法五:字符串强制转数字 a-0

必须是字符串哦!

var a = '11'
var b = a - 0

转换为字符串

方法一:toString()

该方法是内置对象String中的方法,调用者分别有数字类型、布尔类型、对象三种类型。除了null和undefined,其他数据类型均有该方法。

这个方法可以被显式调用,也可以在需要字符串形式时隐式的调用。(既可以显式转换,也可以隐式转换)

1.2.toString();      //"1.2"
true.toString();     //"true"
(10).toString();     //"10" 注意:极小或者极大的数据会生成一个指数形式的字符串哦
(10).toString(16);   //"a"   数字的toString方法可以接受一个基数作为参数。
{}.toString();       //"[object object]"  对于普通的对象而言,如果不是自定义,均会返回对象内部属性[[class]]的值。

在这里我们稍微提一下JSON的stringify(),严格意义上讲,这个并不是强制类型转换函数,我们提到它仅仅是因为这个涉及到了toString强制类型转换。

JSON对象的序列化函数其实也用到了toString(),他们是一套准换规则,只不过JSON.stringify()函数还有除此之外的其他的转换规则。

方法二:String()

String()是一个转型函数,可以将任何类型的值转换成字符串。String函数会先判断值是否有toString方法,如果有就调用,null和undefined单独处理。但String不能数字转换时的基数。所以如果是数字、布尔、对象与toString值一致。如果是null和undefined则返回他们的字符串。

该函数是通过ToPrimitive的抽象来完成的

String(null);          //"null"
String(undefined);     //"undefined"
方法三:加号运算符

将某个值与空字符串连在一起,实现的效果与String一致。

""+true;     //"true"
""+1.2;      //"1.2"
""+null;     //"null"
""+undefined;//"undefined"
注意

在ES6中允许对符号类型强制转换成字符串,但是不能隐式转换。

顺便一提

不能对符号类型转数字,显式隐式都会报错。

可以转布尔,永远是true

所以符号的类型转换应该多加小心。

var a = Symbol('cool')
String(a)//'Symbol(cool)'
a = a+'';//TypeError 

转换为布尔值

像if()等语句中用到的布尔值的地方,js会隐式的进行转换。但是我们还是建议用代码显式转换,增强可读性。

方法一:Boolean()

只有以下七种值为false,其他为true。

Boolean(null);
Boolean(undefined);
Boolean(NaN);
Boolean("");
Boolean(0);
Boolean(-0);
Boolean(false);

在这里我们要注意,封装了假值的对象依然是true,因为他已经是一个对象啦!如:

var a = new Boolean(false)
Boolean(a)//true
方法二:逻辑运算符!

这种方法与Boolean结果一致。注意一般的用法是!!a哦,否则转成了相反的布尔值。

一些提醒

我们在编码时尽可能将类型转换表达清楚,避免给别人留下坑。类型转换越清晰,代码可读性越高,越容易理解。

但是也应该清楚的认识到,隐式类型转换并非一无是处,他的特点是减少冗余,让代码更简洁。他可以让无关紧要的中间步骤被隐藏,从而也提高代码的可读性。我们应该学会取其精华弃其糟粕。

下边真的可以不看 -----

想学习一些前端的书籍吗,我都帮你整理好啦!评论打出你想读的书,给你最全的笔记干货

超级全的前端知识,面试必备、系统复习必备哟哟哟

有想法评论提出哈,欢迎交流,小编也是渣渣一枚呢~一起进步呗

这次真的可以不看 -----

点个收藏呗,要不赞一个呗,小编手都敲累了,但还是持续加更呢~

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值