JavaScript中,基本数据类型有Undefined、Null、Boolean、Number、String,es6新增了一个基本数据类型Symbol。

Undefined类型

Undefined数据类型,只有唯一一个字面值undefined,表示一个值不存在。关于undefined的场景:

  1. 使用声明但是没有初始化的变量,就返回undefined;
  2. 读取一个不存在属性,返回undefined;
  3. 使用了一个没有返回值的函数,返回undefined;
  4. 在函数中读取一个不存在参数,返回undefined;

Null类型

Null类型,表示一个空指针对象,也是只有唯一一个字面量。

在使用typeof运算符检测Null时,会返回object。

关于Null的场景:

  1. 如果我们声明一个变量,是为了接下来要保存某个值,那么就可以在声明的时候,初始化为null;
  2. 没有获取到指定的元素时,会返回null;
  3. 使用正则表达式进行捕获时,没有捕获到结果,就返回null。

null和undefined的相同点:

  1. Undefined和Null类型在转化为Boolean类型时候,都是转为false,所以使用非运算符获取结果为true的时候,不就能判断它的值是undefined还是null;
  2. Undefined类型是派生自Null类型的,所以在非严格模式下,undefined等于null。

null和undefined不同之处

  1. 在使用typeof运算符检测的时候,Undefined类型的值返回"undefined",null返回的是object;
  2. 在通过call调用tostring函数的时候,Undefined返回:“[object Undefined]”,null返回:“[object Null]”。
  3. 在进行字符串转换的时候,null转为"null",undefined转为"undefined";
  4. 在进行数字类型转换的时候,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的一些规则:

  1. true转为1,false转为0;
  2. null转为0
  3. undefined转为NaN
  4. String转为Number:

1、字符串总只有数字,则转为十进制,首位为0,会自动忽略;
2、字符串中含有有效的浮点数,也是按照十进制进行转换;
3、字符串中包含了有效的十六进制格式,那么就会将十六进制转为十进制;
4、空字符串转为0;
5、其他的格式,直接转化为NaN。

  1. Object转Number类型,优先调用valueOf()函数,valueOf函数的返回值按照上面的规则进行转换。

1、Number()函数

Number函数,是可以将任何类型的值转为Number类型,需要遵循这样的规则:

  1. 参数是数字,就直接按照对应的进制格式,统一转为十进制;
  2. 参数Boolean类型的值,true转为1,false转为0;
  3. null转为0
  4. undefined转为NaN
  5. 参数值字符串,

1、这个字符串包含了数字,则直接转换为十进制;会忽略前面的0;
2、字符串是有效的浮点数,则会直接转为对应的浮点数
3、字符串为十六进制,则转为对应的十进制数;
4、字符串为八进制,直接转按照十进制输出,前面的0会忽略;
5、空字符串,返回0;
6、其他情况下会转为NaN

  1. 参数是一个对象,则是先调用valueOf()函数获取返回值,并且将返回值按照上面的规则,进行转换。

2、parseInt()函数

parseInt函数,用来解析一个字符串,返回指定基数对应的整数,比如:parseInt("23",10)

第二个参数默认是10,是转为十进制数。如果对应的字符串不能转为Number,则返回NaN。

parseInt()函数把字符串转为整数,需要遵守以下几个规则:

  1. 非字符串类型转换为字符串类型:优先转为字符串,然后再转换为整数;
  2. 数据截的取前置匹配原则:从字符串的第一个字符开始进行匹配,如果这个字符处于基数的范围内,那么保留,继续往后匹配;如果不满足条件,那么从这个字符开始忽略后面所有字符;
  3. 字符串中含义e,不同的进制,就有不同处理方式,比如:
parseInt(6e3, 10);     // 6000
parseInt(6e3, 16);      // 24576
parseInt('6e3', 10);    // 6
parseInt('6e3', 16);     // 1763
  1. 浮点数的处理:自动忽略小数点后面的数字,直接取整;
  2. 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位,这样就会导致丢失精度,所以就会出现上面的现象。