
2.1 JavaScript数据类型
对于JavaScript这样一个轻量级解释型脚本来说,数据只需在使用或赋值时根据设置的具体内容确定其对应的类型。但是读者需要了解的是,每一种编程语言都有自己所支持的数据类型,JavaScript也不例外。它将其支持的数据类型分为两大类,分别为基本数据类型和复合数据类型。
➢ 基本数据类型:number(数字)、boolean(布尔)、string(字符串)、null(空值)和undefined(未定义)。
➢ 复合数据类型:object(对象)。
其中Object对象分为用户自定义的对象和JavaScript提供的内置对象,在后续的章节中将会对如何使用自定义对象以及内置对象进行详细讲解。
2.1.1 JavaScript基本数据类型
JavaScript提供了typeof方法用于检测变量的数据类型,该方法会根据变量本身的数据类型给出对应名称的返回值。语法格式如下:
语法

对于指定的变量使用typeof方法,其返回值是提示数据类型的文本内容。下面通过示例1来学习typeof运算符的用法。
【示例1】 typeof运算符的用法

示例1在浏览器中的运行效果如图2.1所示。对结果的分析如表2-1所示。

图2.1 示例1运行效果
表2-1 JavaScript基本数据类型

根据上述返回数据类型下面进行具体分析。
1.undefined类型
所有undefined类型的输出值都是undefined。当需要输出的变量从未声明过,或者使用关键字var声明过但是从未进行赋值时会显示undefined字样。例如:

或:


2.null类型
null值表示变量的内容为空,可用于初始化变量,或者清空已经赋值的变量。例如:

3.string类型
在JavaScript中string类型用于存储文本内容,又称为字符串类型。为变量进行字符串赋值时需要使用引号(单引号或双引号均可)括住文本内容。例如:

或:

如果字符串内容本身也需要带上引号,则用于包围字符串的引号不可以和文本内容中的引号相同。例如字符串本身如果带有双引号,则使用单引号包围字符串;反之亦然。例如:

或:

4.number类型
在JavaScript中使用number类型表示数字,其数字可以是32位以内的整数或64位以内的浮点数。例如:

number类型还支持使用科学计数法、八进制数字和十六进制数字的表示方式。
(1)科学计数法
对于极大或极小的数值也可以使用科学记数法表示,写法格式如下:

上述格式表示数值后面跟指数e再紧跟乘以的倍数,其中数值可以是整数或浮点数,倍数可以允许为负数。例如:

变量x1表示的数是3.14乘以10的8次方,即314000000;变量x2表示的数是3.14乘以10的-8次方,即0.0000000314。
(2)八进制与十六进制数
在JavaScript中,number类型也可以用于表示八进制或十六进制的数。八进制的数需要用数字0开头,后面跟的数字只能是0~7(八进制字符)之间的一个。例如:

十六进制的数需要用数字0和字母x开头,后面跟字符只能是0~9或A~F(十六进制字符)之间的一个,大小写不限。例如:

或:

虽然number类型可以使用八进制数或十六进制数的赋值方式,但是执行代码时仍然会将其转换为十进制数结果。
(3)浮点数
要定义浮点数,必须使用小数点以及小数点后面至少跟一位数字表示。例如:

如果浮点数类型的小数点前面整数位为0,可以省略。例如:

浮点数可以使用toFixed()方法规定小数点后保留几位数。其语法格式如下:
语法

其中参数digital是换成小数点后需要保留的位数。例如:

该方法遵照四舍五入的规律,即使进位后小数点后面只有0也会保留指定的位数。例如:

需要注意的是,在JavaScript中使用浮点数进行计算,有时会产生误差。例如:

这是由于表达式使用的是十进制数,但是实际的计算是转换成二进制数计算再转换回十进制数结果的,在此过程中有时会损失精度。此时使用自定义函数将两个加数都乘以10进行计算后再除以10还原。
(4)特殊number值
在JavaScript中,number类型还有一些特殊值,如表2-2所示。
表2-2 JavaScript中number类型的特殊值

①Infinity
Infinity表示无穷大的意思,有正负之分。当数值超过了JavaScript允许的范围就会显示为Infinity(超过上限)或-Infinity(超过下限)。例如:

在比较数字大小时,无论原数据值为多少,结果为Infinity的两个数认为相等,而同样两个-Infinity也是相等的。例如:

上述代码中变量x1与x2的实际数据值并不相等,但是由于它们均超出了JavaScript可以接受的数据范围,因此返回值均为Infinity,从而判断是否相等时会返回true(真)。
在JavaScript中使用数字0作为除数不会报错,如果正数除以0返回值就是Infinity,负数除以0返回值为-Infinity,特殊情况0除以0的返回值为NaN(非数字)。例如:

Infinity不可以与其他正常显示的数字进行数学计算,返回结果均会是NaN。例如:

②NaN
在JavaScript中,NaN是一个全局对象的属性,它的初始值就是NaN,与数字型(number)中的特殊值NaN一样,都表示非数字(Not a Number),可用于表示某个数据是否属于数字型,但是它没有一个确切的值,仅表示非数值型的一个范围。例如,NaN与NaN进行比较时,结果不一定为真(true),这是由于被操作的数据可能是布尔型、字符串型、空值型、未定义型和对象型中的任意一种类型。
通常NaN表示的是非数字(Not a Number),该数值用于表示数据转换成number类型失败的情况,从而无须抛出异常错误。例如将string类型转换为number类型。NaN因为不是真正的数字,不能用于数学计算。并且即使两个数值均为NaN,它们也并不相等。例如将英文单词转换为number类型,就会导致转换结果为NaN,具体代码如下:

JavaScript还提供了用于判断数据类型是否为数字的方法isNaN(),其返回值是布尔值。当检测的数据可以正确转换为number类型时返回真(true),其他情况返回假(false)。其语法规则如下:
语法

例如:

5.boolean类型
boolean类型在很多程序语言中都被用于进行条件判断,其值只有两种:true(真)或者false(假)。boolean类型的变量可以直接使用单词true或false,也可以使用表达式。例如:

其中1>2的表达式不成立,因此返回结果为false(假)。
2.1.2 JavaScript类型转换
1.转换成字符串
在JavaScript中,布尔类型(boolean)和数字型(number)这两种基本数据类型均可使用toString()方法把值转换为字符串形式。
布尔类型(boolean)的toString()方法只能根据初始值返回true或者false。例如:

而数字型(number)使用toString()方法有两种模式,分别称为默认模式和基数模式。在默认模式中,toString()不带参数直接使用,此时无论是整数、小数或者科学计数法表示的内容,都会显示为十进制的数值。例如:

在基数模式下,需要在toString()方法的括号内部填入一个指定的参数,根据参数指示把原始数据转换为二进制、八进制或十六进制数。其中二进制数对应基数2,八进制数对应基数8,十六进制数对应基数16。例如:

由此可见,对于同一个变量使用toString()方法进行转换,如果填入的基数不同会导致返回完全不同的结果。
2.转换成数字
JavaScript提供了两种将string类型转换为number类型的方法:parseInt()和parseFloat(),其中parseInt()用于将值转换为整数,parseFloat()用于将值转换为浮点数。这两种方法仅适用于对String类型的数字内容转换,其他类型的返回值都是NaN。
(1)parseInt()方法
parseInt()方法转换的原理是从左往右依次检查每个位置上的字符,判断该位置上是否是有效数字,如果是则将有效数字转换为number类型,直到发现不是数字的字符,即停止后续的检查工作。例如:

如果需要转换的字符串从第一个位置上就不是有效数字,则直接返回NaN。例如:

由于parseInt()只能进行整数数字的转换,因此检测到某个字符位置上是小数点也会认为不是有效数字,从而终止检测和转换。例如:

parseInt()方法还有一个可选的参数二,可以用于声明需要转换的数字为二进制、八进制、十进制或十六进制数等。例如:

有一种特殊情况需要注意:如果原始数据为十进制数,但是开头包含数字0,则最好使用参数二进行特别强调,否则会被默认转换为八进制数。例如:

(2)parseFloat()方法
parseFloat()方法的转换原理与parseInt()方法类似,都是从左往右依次检查每个位置上的字符,判断该位置上是否是有效数字,如果是则将有效数字转换为number类型,直到发现不是数字的字符,即停止后续的检查工作。
与parseInt()方法类似,如果需要转换的字符串从第一个位置上就不是有效数字,则直接返回NaN。例如:

但是与parseInt()方法不同的是,小数点在parseInt()方法中也被认为是无效字符,但是在parseFloat()方法中首次出现的小数点也被认为是有效的。例如:

如果同时出现多个小数点,也只有第一个小数点是有效的。例如:

和parseInt()还有一个不同之处在于:parseFloat()方法只允许接受十进制数的表示方法,而parseInt()方法允许转换为二进制数、八进制数和十六进制数。
因此八进制数如果是最前面带有数字0的形式,会直接忽略0转换为普通十进制数。例如:

而十六进制数中如果出现字母则直接按照字面的意思认为是无效的字符串。例如:

(3)isNaN()
在实现变量之间的运算时,在实际开发中还需要对转换后的结果是否是NaN进行判断,只有不是NaN时,才能够进行运算。isNaN()函数用于检查其参数是否是非数字,语法格式如下:
语法

如果x是特殊的非数字值,则返回值是true,否则返回false。例如:

isNaN()函数通常用于检测parseFloat()和parseInt()的结果,以判断它们表示的是否是合法的数字。也可以用isNaN()函数来检测算数是否错误,如用0作为除数的情况。
3.强制类型转换
一些特殊的值无法使用toString()、parseInt()或parseFloat()方法进行转换,例如null、undefined等。
此时可以使用JavaScript中的强制转换(Type Casting)对其进行转换。
在JavaScript中有三种强制类型转换函数,解释如下:
➢ Boolean(value):把指定的值强制转换为布尔值。
➢ Number(value):把指定的值强制转换为数值(整数或浮点数)。
➢ String(value):把指定的值强制转换为字符串。
(1)Boolean()函数
在JavaScript中,所有其他类型都可以使用类型转换函数Boolean()转换成布尔值,再进行后续计算。
当需要转换的值为非空字符串时,Boolean()函数的返回值为true;而当需要转换的值为空字符串时,返回false。例如:

当需要转换的值为数字时,整数0的返回值为false,其余所有整数与浮点数的返回值为true。例如:

当需要转换的值为null或undefined时,Boolean()函数的返回值均为false。例如:

当需要转换的值本身就是布尔值时,会转换成原本的值。例如:

(2)Number()函数
在JavaScript中,Number()函数可以将任意类型的值强制转换为数字类型。当需要转换的内容为符合语法规范的整数或小数时,Number()将调用对应的parseInt()或parseFloat()方法进行转换。例如:

当需要转换的值为布尔值时,true会转换为整数1,false会转换为整数0。例如:

与直接使用parseInt()和parseFloat()方法进行数字类型转换不同的是,如果需要转换的值为数字后面跟随超过一个小数点或其他无效字符时,Number()会返回NaN。例如:

当需要转换的值为null或undefined时,Number()函数分别返回0和NaN。例如:

当需要转换的值为其他自定义对象时,返回值均为NaN。例如:

通过前面对转换数字型函数的介绍,我们知道了在使用时是有一定的区别的,具体如表2-3所示。
表2-3 转换数字型函数

表2-3中的所有函数在转换纯数字时会忽略前导零,如“0123”字符串会被转换为123。parseFloat()函数会将数据转换为浮点数(可以理解为小数);parseInt()函数会直接省略小数部分,返回数据的整数部分,并可通过第2个参数设置转换的进制数。
(3)String()函数
在JavaScript中String()函数可以将任意类型的值强制转换为字符串类型并保留字面内容,这与toString()的转换方法类似。与toString()方法不同之处在于,String()函数还可以将null、undefined类型强制转换为字符串类型。例如:

2.1.3 技能训练
上机练习1 统计包含“a”或“A”的字符串的个数
需求说明
使用数组存储一组字符串,并统计包含“a”或“A”的字符串的个数。
运行结果如图2.2所示。

图2.2 统计包含“a”或“A”的字符串的个数
提示
➢ 使用String对象的indexOf()方法判断字符串是否包含特定字符。