在ECMAScript中存在六种数据类型,其中有五种是基本数据类型(Number、String、Boolean、Undefined、Null),一种复杂数据类型(Object)。因为JavaScript数据类型具有动态性, 所以六种数据类型足以表示所有的数据,也因此ECMAScript不支持任何创建自定义类型的机制。

Number

在JavaScript中Number类型是不区分整数值和浮点数值的,所有的数值都是用浮点数来进行表示。
对于整型直接量,我们知道有十进制、八进制和十六进制,这里需要注意的是在ECMAScript的严格模式下,八进制直接量是明令禁止的,会导致JS(JavaScript以下简称:JS)引擎报错。

对于浮点型直接量,该数值中必须包含一个小数点,并且小数点后面必须至少有一位数字;在小数点的前面可以没有数字,但是这种写法是不推荐的。

var floatNum1 = 1.3;
var floatNum2 = 0.1;
var floatNum3 = .3;  //有效,不推荐

数值的存储并不是无限的,它受到内存的限制。

ECMAScript所能表示的最小数值保存在 Number.MIN_VALUE中,打开浏览器控制台:

console.log(Number.MIN_VALUE);  // 输出的结果是:5e-324

ECMEScript所能表示的最大数值保存在Number.MAX_VALUE中,同样的方式在控制台中输出:

console.log(Number.MAX_VALUE); //输出的结果是:1.7976931348623157e+308

通常情况下,我们在计算中很少出现超出范围的情况;如果超出了上限,则会返回 Infinity;如果超出了下限,则会返回-Infinity

如何测试一个数是不是在正常的范围内呢?这里可以用 isFinite() 函数 ,测试该数如果位于最大值和最小值之间则返回true。

var result = Number.MIN_VALUE + Number.MAX_VALUE;
console.log(isFinite(result));   //false

还有个有意思的事,像0/0,infinity/0、infinity/infinity等这种无意义的计算,在JS中并不会报错,而是返回一个NAN(not a number的简称),程序的执行并不会收到影响。

NAN:即非数值(not a number)是一个特殊的数值。表示的是一个 本来要返回数值的操作数 并没有返回数值的情况。

NaN有两个特点:
	1、任何涉及NaN的操作(如:NaN/0)都会返回NaN;
	2、NaN和任何值都不相等,包括自身。

有一个函数叫 isNaN() , 它可以帮助我们确定参数是否"不是数值"。通过该函数,任何不能被转换为数值的值都会导致这个函数返回true。

alert(isNaN(NaN));		//true
alert(isNaN(10));			//false (10是一个数值)
alert(isNaN("10"));			//fasle (“10”可以转换为数值)
alert(isNaN("qixige_xiaowu"));    //true (不能转换成数值)
alert(isNaN(true));			//false  (可以被转换成数值1)

例子中提到非数值转换为数值,我想到了三个可以实现这个功能的函数,他们是 Number()parseInt()parseFloat()

Number():适用于任何数据类型的

parseInt()parseFloat():专门用于把字符串转换成数值

Number()函数的转换规则:
	1、Boolean值:true=1,false=0;
	2、数字值:只做简单的传入和返回;
	3、null:返回0
	4、undefined:返回NaN;
	5、字符串:
		a、只包含数字:都转换为十进制,前面的0会被忽略(如:“070” => 70);
		b、包含浮点格式:转换成对应的浮点数值,前面的0也会被忽略;
		c、包含十六进制:转换成对应的十进制;
		d、空字符串:转换为0;
		e、除上面的情形外,其它的都返回NaN
	6、对象:先调用valueof(),根据上述规则进行转换,若返回NaN;则继续调用toString()方法,在根据上述规则进行转换。

可以看到Number()函数在转换字符串为数值是比较复杂的,所以这下明白为什么要专门有两个函数来单独处理字符串的转换了吧。

parseInt()函数的转换规则:

1、会忽略字符串前面的空格;

2、如果字符串第一个字符不是数字或者负号(也包括空字符串),则返回NaN;

3、直到遇到非数字字符时停止

console.log(parseInt("   1234xiaowu")); // 返回:1234
console.log(parseInt("25.24"));  //返回:25
console.log(parseInt("070")); //返回:70   (在ES5以后,parseInt()不具备解析八进制的能力,所以前面的0会被忽略)

注意
parseInt()函数解析十六进制的字符串格式时,JS引擎会把它当做字符串处理,而返回NaN,例:

console.log(parseInt("AF"));  //返回NaN

要解决十六进制格式的字符串问题,则是需要在parseInt()函数中提供第二个参数,来指定转换时使用的基数,即多少进制。例:

console.log(parseInt("AF",16)); //返回175

继续看下面例子:

console.log(parseInt("10",2));		//按照二进制解析返回 2
console.log(parseInt("10",8));		//按照八进制解析返回 8
console.log(parseInt("10",10));		//按照十进制解析返回 10
console.log(parseInt("10",16);		//按照十六进制解析返回 16

不知道您发现了没有,上面执行console.log(parseInt(“070”));得到的是70的结果;然后又按照console.log(parseInt(“070”,8));执行命令得到的结果是56;

这也是由于好奇的尝试,在ECMAScript标准中不支持使用八进制直接量,但是JS的某些实现是可以允许采用八进制的。

因此呢,这种有些不支持,有些支持的还是说建议不要用啦!

JS这门语言其实坑很多的啦,不入坑怎么成长呢?对吧

parseFloat()函数的转换规则和parseInt()函数类型,但有两点区别:

1、parseFloat()函数遇到第一个小数点是有效的,之后的就无效了

console.log(parseFloat("23.45.67"));  //返回23.45

2、parseFloat()函数始终都会忽略前面的0。

console.log(parseFloat("0xA"));  //返回0  (十六进制格式的字符串始终都会被转换成0)
console.log(parseFloat("0xA",16)); //返回0

String

String类型用于表示由零或多个16位Unicode字符组成的不可变的有序序列。由单引号(’’)或双引号("")表示。

1、字符字面量
JS字符串中,反斜线()后面加一个字符,表示转义。常见的有如下:

\n					换行符
\t					水平制表符
\b					退格符
\r					回车符
\f					换页符
\\					反斜线
\'					单引号
\"					双引号
\xnn				两位十六进制数nn指定的Latin-1字符
\unnnn				四位十六进制数nnnn指定的Unicode字符

获取字符串的长度可以用length属性取得,如:

var text = "welcome to qixige_xiaowu blog";
alert(text.length); //输出29

2、转换为字符串

前面讲到如何将一个字符串转换为一个值。同样的,对于如何把一个值转换成字符串也提供了两种方式:toString() 方法和 String() 方法。

toString():

a: 返回相应值的字符串表现;

var age = 11;
var ageToString = age.toString();   // "11"

**b:**null和undefined值没有这个方法;

var parm = null;
console.log(parm.toString());   //TypeError: Cannot read property 'toString' of null
var parm1 = undefined;
console.log(parm1.toString());  //TypeError: Cannot read property 'toString' of undefined

**c:**可以传递一个参数,输出数值的基数。

var num = 10;
alert(num.toString());			// "10"
alert(num.toString(2));			// "1010"
alert(num.toString(8));			// "12"
alert(num.toString(10));			// "10"
alert(num.toString(16));			// "a'

在不知道要转换的值是null或undefined的情况下,则使用String()函数,该函数可以将任何值转换成字符串。

转换规则如下:

a:有toString()方法的,则调用该方法;

b:null,则返回 “null”;

c:undefined,则返回"undefined"

var value = null;
var value1 = undefined;
alert(String(value));   //"null"
alert(String(value1)); //"undefined"

Boolean

Boolean在开发过程中算是用的最多的一种类型,有两个字面值:truefalse

Boolean类型中的true和false是区分大小写的,除了这一种外的其他形式都是标识符。
在各种数据类型的转换过程中,其中只有***null、undefined、-0、0、NaN、""(空字符串)**转换为boolean后是false,其它的基本上都是true。

Undefined

Undefined是预定义的全局变量(不是关键字)。是变量的一种取值,表明在使用var声明变量的时候未对其进行初始化;

如果要查询某个对象的属性或者数组元素的值是返回的是undefined,则说明该属性或值不存在。

如果函数没有任何的返回值时,也是返回的undefined。

var message;
alert(message == undefined);  //true;

Null

Null表示的是一个空对象指针,在利用typeof操作符检测数据类型的时候,返回object。

var ipad = null;
alert(typeof ipad); //"object"

如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null。

实际上,undefined值是派生自null值的,也因此下面的例子返回的是true的原因。

alert(null == undefined);  //true

不过,操作符"=="出于比较的目的会转换其操作数。尽管null和undefined相等,但是他们有着不一样的用途,无论在什么情况下,都无须显示的给一个变量设置undefined;但null不一样,只要是 保存对象的变量 还没有保存对象的时候,要明确地让该变量保存null值。

参考资料

1、《JavaScript 高级程序设计 (第三版)》 人民邮电出版社

2、《JavaScript 权威指南》机械工业出版社 David Flanagan 著 淘宝前端团队 译