在 JavaScript 中,共有 6 种数据类型,其中有 5 种简单数据类型(String、Number、Boolean、Undefined、Null)和 1 种复杂数据类型(Object)。
## String 类型
`Strinng` 类型,即字符串类型,一般是包含在双引号(")或单引号(')之内。字符串类型有一个特点,就是一但创建,就不能改变它的值,如果需要改变,只能是将原来的字符串销毁,重新创建一个字符串。
~~~
var msg = "Howie"; //定义了一个变量 name ,值为字符串类型的 "howie"
var sex = '男'; //单引号也可以定义字符串
var msg = "Hello " + msg; //此时会重新创建一个新的 9 位数的字符串,再将原来的字符串销毁掉
~~~
* 将其它类型转换为字符串
想要将其它类型转换成字符串类型,需要使用到 `toString()`方法
~~~
var age = 20; //此时的值为一个 number 类型
var ageString = age.toString(); //此时变量 ageString 的值已经变为字符串类型的 “20”了
var flag = true; //此时的值为 boolean 型
var flagStrig = flag.toString(); //此时的值已经是字符串类型的 “true”了
~~~
>[danger] 字符串、数值型、布尔型和对象都会有一个 `toString()` 方法,但 `Null` 和 `Undefined` 没有该方法
如果不知道需要转换的值是什么类型,则可以使用 `String()` 方法进行转换,如果是 `null` 类型,则会转换为 `"null"`,如果是 `undefined` 类型,则会转换为 `"undefined"` 。
~~~
var value1 = 10;
var value2 = true;
var value3 = null;
var value4;
alert(String(value1)); // "10"
alert(String(value2)); // "true"
alert(String(value3)); // "null"
alert(String(value4)); // "undefined"
~~~
>[danger] 当然,除了上面这两种方法可以将其它类型转换为字符串类型,使用操作符加号(+)也可以进行转换。
* 字符字面量
String 数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者具有其他用途的字符。
~~~
\n 换行
\t 制表
\b 空格
\r 回车
\f 进纸
\\ 斜杠
\' 单引号( ' ),在用单引号表示的字符串中使用。例如: 'He said, \'hey.\''
\" 双引号( " ),在用双引号表示的字符串中使用。例如: "He said, \"hey.\""
\xnn 以十六进制代码 nn 表示的一个字符(其中 n 为0~F)。例如, \x41 表示 "A"
\unnnn 以十六进制代码 nnnn 表示的一个Unicode字符(其中 n 为0~F)。例如, \u03a3 表示希腊字符Σ
~~~
## Number 类型
Number 类型,即数值类型,包含整数类型及浮点类型,包含八进制、十进制及16进制
~~~
var num1 = 20; //最常用的 10 进制整数
var num2 = 3.14; //数值型中的浮点数
var num3 = 075; //8 进制,0 开头,其余位数为 0-7
var num4 = 080; //无效的 8 进制,会解析成为 10 进制的 80
var num5 = 059; //无效的 8 进制,会解析成为 10 进制的 59
var num6 = 0x9A5E; //16 进制,0x 开头,其余位数为 0-F,此值转为 10 进制为 39518
~~~
Number 类型分为两种,即整型和浮点型
1. 整型即平时所说的整数,包含 10 进制整数、8 进制整数和 16 进制整数。
1. 浮点型即平时所说的小数,最大的特点就是有一个小数点,并且小数点后面至少得有一位数字,浮点型的最高精度是17位小数,但精度远不如整数,如 `0.1 + 0.2` 的结果并不等于 `0.3` 而是 `0.30000000000000004`,是不是很吃惊?这是因为使用基于IEEE754 数值的浮点计算的通病,并不是ECMAScript 才会这样,其它语言使得这种格式的也会存在这个问题。
~~~
var a = 0.2;
var b = 0.1;
if(a+b == 0.3){
alert('等于');
}else{
alert('不等于');
}
//结果是 “不等于”
~~~
* 储存范围:
在大多数浏览器中,最大值为 `1.7976931348623157e+308`,如果超出这个值,就会自动转为 `Infinity` (正无穷),最小值为 `5e-324`,如果是负数溢出,则会自动转为 `-Infinity`(负无穷)
判断当前浏览器的最大值可以使用 `Number.MAX_VALUE`,判断当前浏览器的最小值可以使用 `Number.MIN_VALUE`。
~~~
alert(isFinite(5 / 0); //true 溢出,0不能作为除数进行运算
~~~
>[danger] 判断一个值是否溢出,可以使用 `isFinite()` 方法,如果没有溢出,返回的是`true`,溢出则返回 `false`
* NaN
NaN(Not a Number),即不是数值的数值类型,在 ECMAScript 中,当运算无法返回正常数值时,就会返回 `NaN`。值得注意的是,任何值与 `NaN` 进行运算后返回值均是 `NaN`,并且`NaN`不与任何值相等,包括`NaN`本身。
判断某个值是否是 `NaN`,可以使用 `isNaN()`函数,该函数接受一个参数,这个参数可以是任何类型,如果是`NaN`则返回 `true`,否则返回`false`。
~~~
alert(isNaN(NaN)); // true
alert(isNaN(20)); // false
alert(isNaN(true)); // false 因为 true 会自动转换为1
alert(isNaN("8")) // fals 因为会被转换为 8
alert(isNaN("Howie")); // true 因为转换后不是一个数字
alert(NaN == NaN); // false NaN不与任何值相等,包括NaN自己
~~~
* 将其它类型转换为数值型
将其它类型转换为数值型,有三个函数:`Number()`、`parseInt()`和`parseFloat()`,其中`Number()`函数可以将任何数据类型转换为数值型,`parseInt()`和`parseFloat()`只能将字符串类型转换为数值型。而这三个函数对同一个数据转换的结果可能会不同,下面看这三个函数的区别:
1.Number()函数
`Number()`函数默认会将数据转换为10进制数值型,如果不能转为数值型,则返回 `NaN`。
~~~
Number(10); // 10 如果本身就是数字,则会原样输出
Number("3.14"); // 3.14 字符串类型的"3.14"会被转换为数值型的 3.14
Number("0010"); // 10 字符串类型的"10"会转换为数值型的 10,忽略前导 0
Number("10abc"); // NaN 无法转换,返回 NaN
Number(true); // 1 boolean 类型的 true 会转换为 1
Number(false); // 0 boolean 类型的 fasle 会转换为 0
Number(undefined); // NaN undefined 会转换为 NaN
Number(null); // 0 Null 直接转换为 0
Number("0xa15"); // 2581 会直接转为 10 进制
Number(""); // 0 空字符串会直接被转换为 0
~~~
>[danger] 如果是对象,则调用对象的 valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是 NaN,则调用对象的 toString()方法,然后再次依照前面的规则转换返回的字符串值
由于在实际使用中,`Number()` 函数转换起来过程比较复杂,所以使用的较少
2. parseInt() 函数
`parseInt()`函数是将字符串类型转为数值型的整型,从第一个字符开始找,如果遇到 `0` 直接忽略,继续向后找,如果遇见正负号或数字,则开始,直到遇到其它字符,则结束,如果一直未遇见其它字符串,则会一直找到字符串末尾。不论是遇到八进制还是十六进制,一律转为十进制。
~~~
var num1 = parseInt("1234blue"); // 1234
var num2 = parseInt(""); // NaN
var num3 = parseInt("a123def"); // NaN
var num4 = parseInt(22.5); // 22
var num5 = parseInt("070"); // 70 // ECMAScrpt 会认为是10进制
var num6 = parseInt("70"); // 70(十进制数)
var num7 = parseInt("0xf"); // 15(十六进制数)
var num8 = parseInt("-8abc"); // -8
~~~
因为在 ECMAScript 5 中,像`070`这种本来应该是 8 进制,但是 ECMAScript 5 认为这是十进制的前导 0,会直接忽略,解析出来的是十制制的 70,所以在 ECMAScript 5 中,`parseInt()`函数提供了第二个参数,八进制直接写 8,16 进制直接写 16,如:
~~~
var num1 = parseInt("070",8); // 56
var num2 = parseInt("0x99",16); // 153
var num3 = parseInt("AB"); // NaN
var num4 = parseInt("AB",16); // 171 同样的字符串,加上第二个参数 16,就会被认为是 16 进制
var num5 = parseInt("101",2); // 5 会被认为是 2 进制
var num6 = parseInt("102",2); // NaN 不合法的 2 进制会被转为 NaN
~~~
3. parseFloat()函数
与` parseInt()`函数类似,`parseFloat()`也是从第一个字符开始解析每个字符。而且也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。也就是说,字符串中的第一个小数点是有效的,而第二个小数点就是无效的了,因此它后面的字符串将被忽略。举例来说,"22.34.5"将会被转换为 22.34。
~~~
var num1 = parseFloat("1234blue"); //1234 (整数)
var num2 = parseFloat("0xA"); //0
var num3 = parseFloat("22.5"); //22.5
var num4 = parseFloat("22.34.5"); //22.34
var num5 = parseFloat("0908.5"); //908.5
var num6 = parseFloat("3.125e7"); //31250000
~~~
>[danger] 建议在使用`parseInt()` 函数时,始终都加上第二个参数,通常都是使用的十进制,所以一般第二个参数为 10
`parseFloat()`是没有第二个参数的,所有的字符串都会被转为十进制数值。
### Boolean 类型
***
Boole 类型也叫“布尔型”,该类型有两个字面值:`true`(真)和`false`(假)。这两个值只能用小写,大写或大小写混合都属于错误语法。布尔型通常用于分支流程控制语句判断。其定义方法为:
~~~
var found = true;
var lost = flase;
~~~
* 将其它类型转换为布尔型
如果想要将其它类型的值转换为布尔型,可以使用 `Boolean()`函数。下面列出各种数据类型转换为布尔型的情况:
| 数据类型 | 转换为`true`的值 | 转换为 `false` 的值 |
| --- | --- | --- |
| Boolean |`true` | `false` |
| String | 任何非空自符串,包括`"0"` | 空字符串(`""`或`''`) |
| Number | 任何非零数值 | `0`和`NaN` |
| Object | 任何对象,包括`[]`和`{}` | `null` |
| Undefined | | `undefined` |
### Undefined 类型
***
`Undefined` 类型只有一个值,即 `undefined`,一般用 `var` 关键字定义的变量,但未赋值或直接赋值为`undefined`时,此时的值就是`undefined`。
~~~
var name = ''; // undefined
var email = undefined // undefined
~~~
### Null 类型
***
Null类型也是只有一个值,就是`null`,用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。
* `null` 与 `undefined` 的区别
说区别之前,先说一下`null`和`undefined`相同的地方。`null`和`undefined`在转换为布尔值时,都会被转换为`false`。
~~~
alert(null == undefined); // true
~~~
区别:
`null`表示"没有对象",即该处不应该有值。而`undefined`表示"缺少值",就是此处应该有一个值,但是还没有定义。
`null`在用`Number()`函数转为数值型时会被转换为`0`,而`undefined`会被转换为`NaN`,`parseInt()`和`parseFloat()`转换时,两者都会被转换为`NaN`。
~~~
Number( null ); // 0
Number( undefined ); // NaN
parseInt( undefined ); // NaN
parseFloat( null ); // NaN
~~~
>[danger] 如果使用`typeof`操作符来判断`null`的话,那么得到的结果将会是`object`
### Object 类型
***
Object 类型即对象类型,而对象其实就是一组数据和功能的集合。对象可以通过执行 new 操作符后跟要创建
的对象类型的名称来创建。
~~~
var obj = new Object();
var obj2 = nwe Object;
~~~
>[danger] 如果在创建对象时,不给构造函数传送参数,那么后面那对小括号是可以省略的,但并不推荐这么做。
Object 的每个实例都具有以下的属性和方法
* `constructor`:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(`constructor`)就是 `Object()`。
* `hasOwnProperty(propertyName)`:用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名(`propertyName`)必须以字符串形式指定(例如: `o.hasOwnProperty("name")`)。
* `isPrototypeOf(object)`:用于检查传入的对象是否是传入对象的原型。
* `propertyIsEnumerable(propertyName)`:用于检查给定的属性是否能够使用 `for-in` 语句来枚举。与` hasOwnProperty()`方法一样,作为参数的属性名必须以字符串形式指定。
* `toLocaleString()`:返回对象的字符串表示,该字符串与执行环境的地区对应。
* `toString()`:返回对象的字符串表示。
* `valueOf()`:返回对象的字符串、数值或布尔值表示。通常与 toString()方法的返回值相同。
### typoof 操作符
***
如果不确定某个数据是哪种类型,可以使用 `typeof`操作符来判断。`typeof`会将判断结果以自符串名形式返回。语法如下
~~~
var name = "Howie";
var age = 20;
alert(typeof name); // string
alert(typeof age); // number
alert(typeof true); // boolean
alert(typeof undefined);// undefined
alert(typeof null); // object
alert(typeof {}); // object
alert(typeof []); // object
~~~
>[danger] typeof 的返回值是该数据类型名称的字符串,因为历史原因, `null`会返回`object`,因为特殊值`null`会被当做一个空的对象引用