[TOC]
## 3.4 数据类型
ECMAScript中有5种简单数据类型(基本数据类型):**Undefined、Null、Boolean、Number和String**。还有1种复杂数据类型-**Object**,Object本质上是由一组无序的名值对组成的。
注:在ES6中新增了Symbol。
### 3.4.1 typeof操作符
JavaScript有三种方法,可以确定一个值到底是什么类型。
~~~
typeof运算符
instanceof运算符
Object.prototype.toString方法
~~~
typeof操作符用来检测给定变量的数据类型,返回下列某个字符串:
~~~
"undefined" 这个值未定义
"boolean" 这个值是布尔值
"string" 这个值是字符串
"number" 这个值是数值
"object" 这个值是对象或null
"function" 这个值是函数
~~~
### 3.4.2 Undefined类型
Undefined类型只有一个值,即特殊的**undefined**。
如果在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined。
~~~
var name;
console.log(name == undefined); // true
~~~
对于未声明过的变量,只能执行一项操作,即使用typeof操作符检测其数据类型(对未声明的变量调用`delete`不会导致错误(在非严格模式下))
### 3.3.3 Null类型
Null类型也是只有一个值的数据类型,这个特殊值就是**null**。null值可以看作是一个**空对象指针**。
~~~
console.log(typeof null); // "object"
~~~
undefined其实是派生自null值:
~~~
console.log(null == undefined); // true
~~~
**注意:**
null和undefined没有属性,甚至连toString()这种标准方法都没有。
**建议:**只要意在保存对象的变量还没有真正保存对象,就应该明确地让变量保存null值,而undefined不必。
### 3.4.4 Boolean类型
Boolean类型有两个字面值:**true和false**,两个值是区分大小写的。
要将一个值转换为其对应的Boolean值,可有使用转型函数Boolean():
~~~
var name = 'tg';
console.log(Boolean(name); // true
~~~
可以对任何类型的值调用Boolean函数,而且总会返回一个Boolean值(true或false)
**转换规则**
| 数据类型 | 转换为true的值 | 转换为false的值 |
| --- | --- | --- |
| Boolean | true | false |
| String | 任何非空字符串 | “”(空字符串) |
| Number | 任何非零数字值(包括无穷大) | 0和NaN |
| Object | 任何对象 | null |
| Undefined | N/A | undefined |
### 3.4.5 Number类型
最基本的数值字面量格式是**十进制整数**。
~~~
var num = 15;
~~~
八进制(以8为基数) 以0开头,后面是(0~7)
~~~
var num = 070; // 八进制的56
~~~
十六进制(以16为基数) 以0x开头,后面是(0~9及A~F),字母A~F可以大小写。
~~~
var num = 0xA; //十六进制的10
~~~
注意:在进行算术计算时,所有以八进制和十六进制表示的数值都会被转换成是十进制。
**1.浮点数值**
浮点数值:数值中必须**包含一个小数点**,且小数点后面必须至少有一位数字。
~~~
var floatNum = 1.1;
~~~
保存浮点数值需要的内存空间是保存整数值的两倍。
对于那些极大或极小的数值,我们可以使用**科学计数法**(e表示法)来表示浮点数值。
e表示法表示的数值等于e前面的数值乘以10的指数次幂:
~~~
var floatNum = 3.125e7; //3125000
var floatNum1 = 3e-7; //0.0000003
~~~
默认情况下,ECMAScript会将那些小数点后面带有6个零以上的浮点数值转换为以e表示的数值。
~~~
var floatNum1 = 3e-7; //0.0000003
~~~
浮点数的最高精度是17位小数。
~~~
0.1 + 0.2 = 0.3000000000000004; // 不是等于0.3
~~~
具体了解可参考下面链接内容:
[http://www.tuicool.com/articles/EryqIzy](http://www.tuicool.com/articles/EryqIzy)
**2.数值范围**
基于内存的限制,ECMAScript只能保存有限的数值。
ECMAScript能够表示的最小数值保存在Number.MIN_VALUE(最小值)中,这个值是**5e-324**;能够表示的最大数值保存在Number.MAX_VALUE(最大值)中,这个值是**1.7976931348623157e+308.**
如果某次计算的结果得到了一个超出JavaScript数值范围的值,那么这个数值就会被转换成特殊的Infinity值;如果这个值是负数,则会被转换为-Infinity(负无穷),如果这个数值是整数,则会转换成Infinity(正无穷)。
注意:Infinity是不能参与计算的数值。
用isFinite()来判断这个值是否无穷,该函数接受一个参数。如果参数位于最小与最大数值之间,返回true。
~~~
console.log(isFinite(1)); //true
console.log(isFinite(Infinity)); // false
~~~
**3.NaN**
NaN(Not a Number)表示**非数值**,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况。
**特点**:
* **任何涉及NaN的操作都会返回NaN。**
~~~
console.log(typeof NaN/10); //NaN
~~~
* **NaN与任何值都不相等,包括NaN本身。**
~~~
console.log(NaN == NaN); //false
~~~
ECMAScript定义了isNaN()函数来判断是否非数值,该函数接受一个**参数,可以是任何类型**。
console.log(isNaN(NaN)); // true
isNaN()在接收到一个值(可以是任何类型)之后,会**尝试将这个值转换为数值**,某些不是数值的值会直接转换为数值,而任何**不能被转换为数值的值**都会导致这个函数返回**true**。
~~~
console.log(isNaN(NaN)); // true
console.log(isNaN(10)); // false
console.log(isNaN("10")); //false (可以转成数值10)
console.log(isNaN(true)); //false (可以转成数值1)
console.log(isNaN('blue')); //true
~~~
**4.数值转换**
有3个函数可以把非数值转换为数值:**Number()、parseInt()和parseFloat()**
Number()可以用于任何数据类型,后面两个是专门用于把字符串转换为数值。
**Number()函数的转换规则:**
* 如果是Boolean值,true和false将分别转换为1和0
* 如果是数字值,只是简单的传入和返回
* 如果是null值,返回0
* 如果是undefined,返回NaN
* 如果是字符串,遵循下列规则:
1. 如果是字符串中只包含数字(包括前面带正负号),则将其转换为十进制数值(前导的零会被忽略)
2. 如果字符串中包含有效的浮点格式,如1.1,则将其转换为对应的浮点数值
3. 如果字符串中包含有效的十六进制,如0xf,则将其转换为相同大小的十进制数值
4. 如果字符串是空的,返回0
5. 如果字符串中包含上述格式以外的字符,返回NaN
* 如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回字符串值
~~~
console.log(Number('tg')); // NaN
console.log(Number('')); // 0
console.log(Number('0011')); // 11
console.log(Number(true)); //1
~~~
一元加操作符的操作与Number函数规则相同。
**parseInt()函数转换规则:**
parseInt()会忽略字符串前面的空格,直到找到第一个非空格字符。**如果第一个字符不是数字字符或负号,就会返回NaN。如果第一个字符是数字字符,就会继续解析,直到解析完所有后续字符或者遇到了一个非数字字符.**
parseInt()也能识别八进制(在ECMAScript 5中无法识别,将开头的0当作0)和十六进制,最后会转换成十进制。
~~~
console.log(parseInt('123tg')); // 123
console.log(parseInt('')); // NaN
console.log(parseInt('070')); // 70
console.log(parseInt('0xf')); //15
console.log(parseInt(22.5)); // 22
~~~
我们还可以为parseInt()提供第二个参数,指定需要转换的进制。如果提供了第二个参数,要转换八进制和十六进制时,可省略0和0x。
~~~
console.log(parseInt('0xAF',16)); // 175
console.log(parseInt('AF',16)); // 175
console.log(parseInt('AF')); // NaN
console.log(parseInt('070',8)); // 56
console.log(parseInt('70',8)); // 56
~~~
**parseFloat()**和parseInt()类似,也是从第一个字符(位置0)开始解析每个字符,而且一直解析到字符串末尾,或者解析到遇到一个无效的浮点数字字符为止。
即:字符串中的第一个小数点是有效的,后面的小数点是无效的,它还会忽略前导的零,只会解析十进制值。
~~~
console.log(parseFloat('123tg')); // 123
console.log(parseFloat('22.12.4')); // 22.12
console.log(parseFloat('070')); // 70
console.log(parseFloat('0xf')); //0
console.log(parseFloat(22.5)); // 22.5
~~~
### 3.4.6 String类型
String类型用于表示由零或多个16位Unicode字符组成的字符序列,即**字符串**。字符串可以由双引号或单引号表示(前后一致则无区别)。
~~~
var name = 'tg'; 或 var name = "tg";
~~~
在ECMAScript 3中,字符串直接量必须写在一行中,而在ECMAScript 5中,字符串直接量可以拆分成数行,每行必须以反斜杠(\)结束。
~~~
// ES 5
'Hello \
world'
~~~
**1.字符字面量**
String数据类型包含了一些特殊的字符字面量,也叫**转义序列**,用于表示非打印字符,或者具有其他用途的字符。
这些字符字面量可以出现在字符串中的任一位置,而且也被当作**一个字符**来解析。
| 字面量 | 含义 |
| --- | --- |
| \n | 换行 |
| \t | 制表 |
| \b | 空格 |
| \r | 回车 |
| \f | 进纸 |
| \\ | 斜杠 |
| \' | 单引号 |
| \" | 双引号 |
| \xnn | 以十六进制代码nn表示的一个字符(n为0~F),比如:\x41表示"A" |
| \unnn | 以十六进制代码nnnn表示的一个Unicode字符(n为0~F)。比如:\u03a3表示Σ |
~~~
var name = 'tg\u03a3';
console.log(name); //tgΣ
console.log(name.length); // 3
~~~
**2.字符串的特点**
ECMAScript中的字符串是不可变的。一旦创建,值就不会改变。
**后台逻辑:**要改变某个变量保存的字符串,首先要销毁原来的字符串,然后用另一个包含新值的字符串填充该变量。
**3.转换为字符串**
要将一个值转换为字符串有两种方式:
使用几乎每个值(null和undefined没有)都有的**toString()**方法
还可以给toString()传入一个参数作为输出数值的基数。
~~~
var num = 10;
alert(num.toString()); //"10"
alert(num.toString(2)); //"1010
~~~
可以使用转型函数**String()**,**能将任何类型的值转换为字符串**,转换规则:
* 如果值有toString()方法,则调用该方法并返回相应的结果
* 如果值是null,则返回null
* 如果值是undefined,则返回undefined
~~~
console.log(String(10)); // "10"
console.log(String(true)); // "true"
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
~~~
要把某个值转为字符串,还可以使用加号操作符实现隐式转换
~~~
console.log( true + ''); // "true"
~~~
### 3.4.7 Object类型
ECMAScript中的对象其实就是**一组数据和功能的集合**。对象可通过执行new操作符后跟创建的对象类型的名称来创建。
~~~
var o = new Object();
~~~
**在ECMAScript中,Object类型是所有它的实例的基础,即Obeject类型所具有的任何属性和方法也同样存在于更具体的对象中。**
Object的每个实例都具有下列属性和方法:
~~~
Constructor:保存着用于创建当前对象的函数,比如上面的例子,构造函数就是Object()
hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中是否存在(而不是在实例的原型中),参数必须是字符串形式
isPrototypeOf(object):用于检查传入的对象是否是另一个对象的原型
propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举,参数必须是字符串形式
toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应
toString():返回对象的字符串表
valueOf():返回对象的字符串、数值或布尔值表示,通常和toString()返回的值相同
~~~
- 前言
- 第一章 JavaScript简介
- 第三章 基本概念
- 3.1-3.3 语法、关键字和变量
- 3.4 数据类型
- 3.5-3.6 操作符、流控制语句(暂略)
- 3.7函数
- 第四章 变量的值、作用域与内存问题
- 第五章 引用类型
- 5.1 Object类型
- 5.2 Array类型
- 5.3 Date类型
- 5.4 基本包装类型
- 5.5 单体内置对象
- 第六章 面向对象的程序设计
- 6.1 理解对象
- 6.2 创建对象
- 6.3 继承
- 第七章 函数
- 7.1 函数概述
- 7.2 闭包
- 7.3 私有变量
- 第八章 BOM
- 8.1 window对象
- 8.2 location对象
- 8.3 navigator、screen与history对象
- 第九章 DOM
- 9.1 节点层次
- 9.2 DOM操作技术
- 9.3 DOM扩展
- 9.4 DOM2和DOM3
- 第十章 事件
- 10.1 事件流
- 10.2 事件处理程序
- 10.3 事件对象
- 10.4 事件类型
- 第十一章 JSON
- 11.1-11.2 语法与序列化选项
- 第十二章 正则表达式
- 12.1 创建正则表达式
- 12.2-12.3 模式匹配与RegExp对象
- 第十三章 Ajax
- 13.1 XMLHttpRequest对象
- 你不知道的JavaScript
- 一、作用域与闭包
- 1.1 作用域
- 1.2 词法作用域
- 1.3 函数作用域与块作用域
- 1.4 提升
- 1.5 作用域闭包
- 二、this与对象原型
- 2.1 关于this
- 2.2 全面解析this
- 2.3 对象
- 2.4 混合对象“类”
- 2.5 原型
- 2.6 行为委托
- 三、类型与语法
- 3.1 类型
- 3.2 值
- 3.3 原生函数