JavaScript中,基本数据类型有Undefined、Null、Boolean、Number、String,es6新增了一个基本数据类型Symbol。
Undefined类型
Undefined数据类型,只有唯一一个字面值undefined,表示一个值不存在。关于undefined的场景:
- 使用声明但是没有初始化的变量,就返回undefined;
- 读取一个不存在属性,返回undefined;
- 使用了一个没有返回值的函数,返回undefined;
- 在函数中读取一个不存在参数,返回undefined;
Null类型
Null类型,表示一个空指针对象,也是只有唯一一个字面量。
在使用typeof运算符检测Null时,会返回object。
关于Null的场景:
- 如果我们声明一个变量,是为了接下来要保存某个值,那么就可以在声明的时候,初始化为null;
- 没有获取到指定的元素时,会返回null;
- 使用正则表达式进行捕获时,没有捕获到结果,就返回null。
null和undefined的相同点:
- Undefined和Null类型在转化为Boolean类型时候,都是转为false,所以使用非运算符获取结果为true的时候,不就能判断它的值是undefined还是null;
- Undefined类型是派生自Null类型的,所以在非严格模式下,undefined等于null。
null和undefined不同之处
- 在使用typeof运算符检测的时候,Undefined类型的值返回"undefined",null返回的是object;
- 在通过call调用tostring函数的时候,Undefined返回:“[object Undefined]”,null返回:“[object Null]”。
- 在进行字符串转换的时候,null转为"null",undefined转为"undefined";
- 在进行数字类型转换的时候,undefined转换为NaN,null转为0,参与计算;
Boolean类型
Boolean类型,有两个字面量false和true。
在平时的开发中,不同类型与Boolean类型值的转换,才是Boolean类型的重点。
1、String类型转为Boolean类型
任何空字符串都会转为false,任何非空字符串就会转为true
2、Number类型转为Boolean类型
0和NaN会转为false,其他值都会转为true
3、Object类型转Boolean
object为null时,会转为false,其他任何场景下,都会转为true
4、Function类型转Boolean
任何时候,Function类型的值都会转为true
5、null转为false
6、undefined转为false
Number类型
其他类型转为Number的一些规则:
- true转为1,false转为0;
- null转为0
- undefined转为NaN
- String转为Number:
1、字符串总只有数字,则转为十进制,首位为0,会自动忽略;
2、字符串中含有有效的浮点数,也是按照十进制进行转换;
3、字符串中包含了有效的十六进制格式,那么就会将十六进制转为十进制;
4、空字符串转为0;
5、其他的格式,直接转化为NaN。
- Object转Number类型,优先调用valueOf()函数,valueOf函数的返回值按照上面的规则进行转换。
1、Number()函数
Number函数,是可以将任何类型的值转为Number类型,需要遵循这样的规则:
- 参数是数字,就直接按照对应的进制格式,统一转为十进制;
- 参数Boolean类型的值,true转为1,false转为0;
- null转为0
- undefined转为NaN
- 参数值字符串,
1、这个字符串包含了数字,则直接转换为十进制;会忽略前面的0;
2、字符串是有效的浮点数,则会直接转为对应的浮点数
3、字符串为十六进制,则转为对应的十进制数;
4、字符串为八进制,直接转按照十进制输出,前面的0会忽略;
5、空字符串,返回0;
6、其他情况下会转为NaN
- 参数是一个对象,则是先调用valueOf()函数获取返回值,并且将返回值按照上面的规则,进行转换。
2、parseInt()函数
parseInt函数,用来解析一个字符串,返回指定基数对应的整数,比如:parseInt("23",10)
,
第二个参数默认是10,是转为十进制数。如果对应的字符串不能转为Number,则返回NaN。
parseInt()函数把字符串转为整数,需要遵守以下几个规则:
- 非字符串类型转换为字符串类型:优先转为字符串,然后再转换为整数;
- 数据截的取前置匹配原则:从字符串的第一个字符开始进行匹配,如果这个字符处于基数的范围内,那么保留,继续往后匹配;如果不满足条件,那么从这个字符开始忽略后面所有字符;
- 字符串中含义e,不同的进制,就有不同处理方式,比如:
parseInt(6e3, 10); // 6000
parseInt(6e3, 16); // 24576
parseInt('6e3', 10); // 6
parseInt('6e3', 16); // 1763
- 浮点数的处理:自动忽略小数点后面的数字,直接取整;
- map()和parseInt()函数隐藏的巨坑,有这样的案例:
var arr = ['1', '2', '3', '4'];
var result = arr.map(parseInt);
console.log(result);
可以才想一下result的结果,真实结果为:[1,NaN,NaN,NaN],而不是[1,2,3,4]。
因为在map遍历中,会默认将index作为parseInt的基数,这样遍历到第一个数字的时候,就是碰巧运气好,通过了;遍历到第二个数字的时候,代码是:parseInt("2",1)
,然而parseInt的基数是2到36之间,1不符合,因此返回NaN。
遍历到第三个数字的时候,表示的是将3处理为二进制表示,实际上二进制时只有0和1,3超出了二进制的表示范围,无法转换,返回“NaN”,以此类推,后面的结果也是NaN。
浮点数运算
在JavaScript中,浮点数和整数,都是采用64位进行存储的。但是在进行运算的时候,就会出现一些差异;
比如:
// 加法
0.1 + 0.2 = 0.30000000000000004
0.7 + 0.1 = 0.7999999999999999
// 减法
1.5 - 1.2 = 0.30000000000000004
0.3 - 0.2 = 0.09999999999999998
// 乘法
0.7 * 180 = 125.99999999999999
9.7 * 100 = 969.9999999999999
// 除法
0.3 / 0.1 = 2.9999999999999996
0.69 / 10 = 0.06899999999999999
浮点数在计算机中的表示,总长度是64位,最高位是符号位,接着往后11位是指数位,最后的52位是小数位,也就是有效数字的部分。
所以在存储浮点数的时候最多只能存储52位。那么对于一些无限循环的小数来说,只会截取前面的52位,这样就会导致丢失精度,所以就会出现上面的现象。