js基础阵营:变量篇之类型转换
前面我们已经讲解了变量的类型,在上一章,我们了解了基础的类型以及类型的含义以及用法。在这一章中,我们将了解变量的转换的一些知识。
首先我们要了解什么是类型转换,顾名思义就是将数据类型进行转换,例如原有的类型是一个number类型将其转换成string类型,这就是所谓的类型转换。
在JS中我们常见的类型转换有两种,显式类型转换和隐式类型转换下面我们一一来说明
一:显式类型转换
顾名思义,是一种显而易见的类型转换,也就是说我们或者编译器通过代码就能清楚的知道是要进行类型转换。下面我们看下常见的几种显式类型转换
字符串与数字间的类型转换
在js中字符串通过String()或者toString(),数字通过Number()来进行显示的类型转换,看下面的代码
var total = 12;
var totalStr= '12';
console.log(typeof String(total)) // string
console.log(typeof total.toString()) // string
console.log(typeof Number(totalStr)) // number
对于强制转换成字符串从我的角度觉得没有什么好说明的,但是对于Number就需要跟我们解析数字字符串方法进行对比了。我们来看下以下代码
var total = '12';
var totalName = '12个';
console.log(Number(total)); // 12
console.log(parseInt(total)); // 12
console.log(Number(totalName)); // nan
console.log(parseInt(totalName)); // 12
为什么会出现这种不一致的情况呢?其实很简单,因为解析方法(parseInt,parseFloat)在解析的时候允许字符串中出现非数字,其解析会解析到非数字的字符,然后将数字返回,而Number强制类型转换,是需要将字符串显示的的转成数字,如果出现非数字的情况自然而然的会需要提示此字符串不是一个数字,所以无法转换。那么parseInt是如何解析的呢?
我们可以看到此方法接受两个参数,参数1为一字符串,参数二为一基数。默认基数为10.因此执行的过程为
1:将参数转换成字符串
2:然后从开头进行解析,解析到第一个非数字的字符为止。
因此,我们可以来看看以下的代码
console.log(parseInt(0.01)) // 0
console.log(parseInt(0.0000008)); // 8
console.log(parseInt({
num:12
})); // NAN
console.log(parseInt({
num:12,
toString:function(){return 24}
})); // 24
parseInt(parseInt,16); // 15
为什么和我们想象的不一样呢,具体原因就是我前面提到的,参数会先转换成字符串,然后进行解析。所以我们可以一一来看上面的问题
1: 0.01,转换成字符串是'0.01',解析到.的时候结束,所以为0
2:0.0000008,转成成字符串,由于位数很大,故为'8e-7',解析到e为止,故为8
3:{num:12} ,是一 对象,再执行其toString方法后会变成'[object Object]',故NAN
4: { num:12,toString:function(){return 24}},因为重新的toString方法,在执行转换成字符串的时候,执行toString方法,故24
5:parseInt方法在执行toString()方法后是一个function,执行16进制,为15
显示转换为布尔类型
在JS中提供一Boolean方法,其方法可以将传入的参数转换为true和false,那么具体哪些值会转换成true哪些会转换成false呢?看下表
数据类型 | true | false |
---|---|---|
字符串 | 非空字符串 | '' |
数字 | 非0数字 | 0 |
布尔类型 | true | false |
对象 | 所有数组,对象,方法 | 无 |
null | 无 | null |
undefined | 无 | undefined |
二:隐式类型转换
顾名思义,与显示的类型转换相反,不是显示的去告诉人们以及编译器需要转换的格式,而有编译器根据一些规则,自动的去转换。下面我们来看看常见的隐式转换
数字和字符串间的隐式转换
我们首先来看下以下代码
var a = '12';
var b = '0';
var c = 12;
var d = 0;
var e = [1,2];
var f = 3;
console.log(a + b); // '120'
console.log(c+ d); // 12
console.log(e + f); // 1,23
为什么会这样呢?首先我们来看+的作用,在js中其既能当做一个数字的加也可作为字符串拼接。所以有了以下规则
1:如果数据类型皆为数字,则执行加法
2:如果数据类型不同,在执行字符串拼接。字符串拼接又有如下规则:
1:将数据转换成字符串,对象以及数组调用其toString方法。
2:将字符串进行拼接。
按照以上规则,所以以上代码的执行结果也就能理解了
隐式转换为布尔类型数据
相比字符串以及数字,转换成布尔类型的情况就很明显,一般会在以下几种情况下会出现
1:if语句中
2:for循环的第二个判断中
3:while循环中
4:逻辑与(&&)或非(||)中
5:三元运算符中
对此就不一一说明了,因为都是常见的方法。
判断相等(==)
其实在日常开发中,我们如果需要判断相同的情况不推荐使用==而是推荐===,具体原因就是==会将数据进行隐式的类型转换,从而导致判断不准确。我们先来看看以下代码
console.log(12=='12'); // true
console.log(true == 12); // false
console.log(true == '12'); // false
console.log(null == 12); // false
console.log(null == false); // false
console.log(null == undefined); // true
console.log(undefined == false); // false
console.log(null == 0); // false
console.log(undefined == 0);// false
console.log({a:12} == true);// false
console.log({a:12,toString:function(){return 0}} ==false);//true
为什么会有很多跟我们设想的不一样呢?我们先来看看js的规则。
1:如果双方类型相同,则执行该类型下的对比方法
2:如果为字符串和数子对比,则将字符串强制转换成数子(Number)然后执行数子间的比对
3:如果存在布尔类型,将布尔类型转换成数子,然后进行数子间的比对
4:如果存在对象,则执行对象toString()方法后再按照以上规则执行
按照以上逻辑我想上面的结果也就很明确了.
ps:上面提到过将数组以及对象转换成基本类型后再进行数据对比,那么具体的规则是什么呢?
1:查看需要转换的值是否有valueof方法,
2:如果存在valueOf方法,如果有且返回的是基本类型,则用此返回
3:如果不存在valueOf方法,或者valueOf方法返回的不是基本类型,那么则调用toString方法
以上为本次的类型转换,下面我们将讲解特殊的变量数组,以及其常见的方法