解析JS的数据类型转换

2016-07-12

如果说你要成为一名JSer,那么对JS的一些原理机制肯定是要去了解的。如果你和其它刚刚学习到web开发课程的同学一样,只会用JS写写alert,写写表单验证,那么是绝对不够的。


今天我想说的是 JS的数据类型转换。因为这一块自己之前是挺模糊的。主要原因我是归结于《Javascript高级程序设计》在这一块的描述太散,太拖沓。导致我没多大耐心去分析。但是,难啃的骨头终归还是要啃的,那么还不如直面这个问题。


PS:下面的内容可能与数据类型转换无关,仅为个人吹水所写,若赏脸,就请看那么一两下,若不然,请跳过。


首先,一开始当然是要介绍JS的数据类型,基本的数据类型有:Number,String,Boolean,比较特殊的有undefined和null,最后要重点介绍的肯定是Object啦。(如果要深入去较真的话,你可以把Object分为Function,Array,Date等)


那么我们所说的数据类型转换,肯定就是涉及到上述类型的转换。如果说得再确切一点的话,是其它类型数据转换为Number,String,Boolean这三种基本类型。


那么,数据类型转换有多少种形式呢?我在这里我会告诉大家,只有一种——就是强制类型转换。估计看到这里,部分有了解过这方面知识的同学肯定会破口大骂我是水货!但是且别急,我觉得,学习JS,就请不要把你们学习C语言,学习Java的那一套照搬过来。如果你愿意,请看我的分析。


首先,触发数据类型转换的条件无非是不同类型间的运算。这些运算可能包括:自然运算(加减乘除),字符串拼接,逻辑运算等。那么归根到底,我们要运算,终归要将其变成相同的数据类型才能进行。所以,对于不同类型的变量,我们要“强制”将其变为解析引擎能够接受的类型。而这个“强制”的过程到底是我们自己手动地用代码转换还是由引擎自己自动地转换,并不影响结果。


上面所说的自动还是手动,对应的就是一些JS教程里面的强制类型转换和自动类型转换(有些书称为隐式转换)。但是事实上原理都是一致的。所以请大家不要想那么复杂。


PS:吹水内容结束==========================================================================


刚刚说了,数据类型转换其实就是不同类型的转换,所以我们只要掌握其它类型转为特定类型的方法就好了,下面是具体实现:

1.其它类型转Number,我的记忆法则是:【是数字就不用转】【字符串中若包含数字就转,不包含则为NaN】【false为0,true为1】【undefined为NaN,null为0】

2.其它类型转String,【它原来长什么样就转成什么样的字符串】

3.其它类型转Boolean,【(0,-0,NaN,空字符串,null,undefined)这六个永远为false,其它都为true】

好了,说完了?有人又要骂我了。那对象转这些类型呢?

那我们要谈一谈valueOf和toString这两个方法了。这两个方法是继承于Object的。也就是说,只要是个对象,你就有这俩方法。这俩方法有嘛用呢?最主要的用途就是数据类型转换。确切地说是对象的数据类型转换。而之所以上面没有提及对象的数据类型转换,是因为它有套路。且听我说:

1.若对象转Number,则对象会先调用valueOf方法,若此时得到的数据类型不为Number,那么再调用toString方法,若再得不到Number类型,那就抛typeError异常。

2.若对象转String,则对象会先调用toString方法,若此时得到的数据类型不为String,那么再调用valueOf方法,若再得不到String类型,那么解析引擎拿你没办法,直接抛出typeError。

3.若对象转Boolean,则甭谈了,只要是对象都为true。甚至是这样var bool = Boolean(new Boolean(false));结果仍然为true,不信你试试?

好了,这样一来,基本的数据类型转换套路我就说完了。接着就是一些特殊情况。那么让我们来看看有哪些要注意的东西:

1 + {};

结果是?加法运算,左边是Number了,右边对象,于是先调用valueOf,返回对象本身,不为Number,再调用toString,返回[Object object],是String类型,也不为Number,那么抛出typeError。

是这样吗?不是!这有加号就一定要做加法么?你是程序员还是小学生呢?加法还能代表字符串拼接。JS解析的时候,若进行加法运算不成功则会尝试进行字符串拼接。也就是说,当右边的变量出现String的时候,就会把左边的Number转换成字符串,所以上面运行的结果是——"1[Object object]",这一点提醒大家,在进行‘+’运算的时候要注意判断到底最后是进行加法运算还是字符串拼接。

{} + {}

结果是:[Object object][Object object],对不对?很遗憾,错了。反正我不知道为啥,反正结果返回NaN。但是如果测试:{} + 1的话,结果返回1,也就是说,前面一个{}没有被识别为对象。所以后面的对象返回一个String,而加号在这里进行的是正值转换,故强制将String转换成Number,结果为NaN。解决方法:

({}) + {}

解析引擎会对括号内的运算进行求值,所以括号里的{}会被转换成对象,所以这样返回的结果才是:[Object object][Object object]

好了,到此,所有的类型转换该注意的点我全部讲完了。如果哪里说的不好,还请大家指正!