JS 数据类型分为基本数据类型、复杂数据类型(也叫做引用数据类型)
JS 基本数据类型
Undefined
定义
Undefined 类型只有一个值,就是特殊值 undefined. 当使用 var 或者 let 声明了变量但是没有初始化时,相当于给变量赋予了 undefined 值
let message
console.log(message == undefined) // true
console.log(typeof message) // undefined
// 注意:对于一个未声明的变量使用 typeof 类型检测,值也是 undefined
console.log(typeof age) // undefined
注意:
- 对于一个未声明的变量使用 typeof 类型检测,值也是 undefined(例子看上面代码)
- 虽然未初始化的变量会自动赋予 undefined 值,但是仍然建议在声明变量的同时进行初始化。
-
- 这样我们使用 typeof 检测类型得到 undefined 时,就可以知道是声明了但是未初始化,还是未声明
Null
定义
Null 类型同样只有一个值,即特殊值 null. 逻辑上讲,null 的值表示一个空对象指针。
注意
-
在定义将来要保存对象值的变量时,建议使用 null 来进行初始化,不要使用其他值
-
null 是 由 undefined 值派生而来的
console.log(null == undefined) // true -
null 和 undefined 有关系,但是用途却不一样
-
- 对于 undefined,我们永远不需要显式地将变量值设置为 undefined
- 对于变量,只要保存对象,而当时又没有那个对象可以保存,可以先用 null 类进行填充。(这样就可以保持 null 是空指针的语音,也进一步与 undefind 进行区分)
-
使用 typeof 检测 null 类型时返回 object
console.log(typeof null) // "object"
Number
定义
ECMAScript 中最有意思的数据类型。Number 类型使用 IEEE 754 格式表示整点数和浮点数(在某些语言中也叫做双精度)
数值字面格式
- 十进制(最基本的数值字面量格式)
- 八进制
-
- 第一个数字必须是0,然后后面是相应的八进制数字0-7
- 八进制在严格模式下是无效的,会导致 JavaScript 引擎抛出语法错误
- 十六进制
-
- 前缀必须是 0x(区分大小写),然后是十六进制数字(0-9以及A-F)
- 十六进制数字钟的字母大小写均可
let hexNum1 = 0xA; // 十六进制 10 let hexNum2 = 0x1f; // 十六进制 31
浮点数
- 要定义浮点数,数值中必须包含小数点,并且小数点后面必须至少有一位数字。
- 因为存储浮点数使用的存储空间是存储整数值的两倍,所以ECMAScript 总是想方设法把值转换为整数。小数点后面没有数字情况下,数值就会变为整数。
- 对于非常大或者非常小的数值,浮点数可以使用科学计数法来表示。
-
- 默认情况下,ECMAScript 会将小数点后至少包含6个零的浮点值转换为科学计数法
0.000 0003 => 3e-7 -
浮点数的精度最高可达17位,但是在算术运算中远不如整数精度
-
0.1 + 0.2 = 0.30000000000000004
let a = 0.1 let b = 0.2 if(a + b === 0.3){ // 千万别这么干 }
值的范围
- ECMAScript 可以表示的最小数值保存在 Number.MIN_VALUE 中,这个值在大多数浏览器中是
5e-324 - 可以表示的最大值保存在 Number.MAX_VALUE 中,这个值在多数浏览器中是
1.797 693 134 862 3156 7e+308 - 超出最大值, 这个值会自动转换为一个特殊的
Infinity无穷值 - 任何无法表示的负数以
-Infinity负无穷大表示,任何无法表示的整数以Infinity表示 - 可以使用
isFinite函数来判断一个数值是不是有限大(即介于JavaScript 能表示的最大值和最小值之间)
NaN
特殊值 NaN: Not a Number,不是一个数值。用于表示本来要返回数值的操作失败了(而不是抛出错误)
console.log(0/0) // NaN
console.log(-0/0) // NaN
- 任何涉及 NaN 的操作始终返回 NaN ( 如 NaN + 10)
- NaN 不等于包含 NaN在内的任何值
- isNaN 函数:接受一个参数,可以是任意数据类型,然后判断这个参数是否“不是数值”
-
- 任何不能转换为数值的值都会导致这个函数返回 true
数值转换
- parseInt()
-
- 字符串前面的空格会被忽略,从第一个非空格字符开始转换
- 会依次检测每个字符,直到字符串结尾,或者碰到非数值字符
- 第二个参数可以指定底数(进制数),不传底数就相当于让 parseInt 自己决定如何解析,所以为了避免解析错误,建议始终传递第二个参数
- parseFloat()
-
- 解析处理方式和 parseInt 类似,都是从位置0开始检测字符,直到字符末尾或者解析到一个无效的浮点数值字符为止
- 另一个不同在于,它会忽略字符串开头的零
- 它只能解析十进制数值,不能指定底数
- Number()
注意
-
正零(+0)和 负零(-0)在所有情况下都被认为是等同的
-
0.1 + 0.2 !== 0.3
-
任何涉及 NaN 的操作始终返回 NaN ( 如 NaN + 10)
-
NaN 不等于包含 NaN在内的任何值
console.log(NaN == NaN) //false -
使用 parseInt 时,建议添加第二个参数,指定解析进制数
-
使用 parseFloat 只能解析十进制,不能指定底数
String
定义
用来表示零或者多个 16位 Unicode 字符序列。可用单引号、双引号、反引号来标示
特点
- ECMAScript 中的字符串是不可变的
-
- 一旦创建,他们的值就不能变了
- 要修改某个变量中的字符串,就必须先销毁原始字符串,然后将一个新的字符串保存到变量中
转换为字符串
- 几乎所有值都有对应的 toString() 方法:这个方法唯一的作用就是返回当前值的字符串等价物
-
- null 和 undefined 没有 toString 方法
- toString() 接受一个底数参数,默认是 十进制底数
- String() 方式转换
Boolean
定义
布尔值是 ECMAScript 中使用最频繁的类型之一,有两个字面量:true 和 false
注意
- 布尔值字面量 true 和 false 是区分大小写的
-
- True 和 False 是有效的标识符,但不是布尔值
转换规则
| 数据类型 | 转换为 true 的值 | 转换为 false 的值 |
|---|---|---|
| Boolean | true | false |
| String | 非空字符串 | 空字符串""(包含换行符\r\n等) |
| Number | 非零数值(包括无穷大) | 0、NaN |
| Object | 任意对象 | null |
| Undefined | N/A(不存在) | undefined |
Symbol(ES6 新增数据类型)
基本定义
Symbol 本质上是一种唯一标识符,可用作对象的唯一属性名,这样其他人就不会改写或覆盖你设置的属性值。
特点:
唯一性
即使是用同一个变量生成的值也不相等。
let id1 = Symbol('id');
let id2 = Symbol('id');
console.log(id1 == id2); //false
不可遍历性
- for···in,object.keys() 不能访问
let id = Symbol("id");
let obj = {
[id]: 'symbol'
};
for (let option in obj) {
console.log(obj[option]); //空
}
- 可以通过 Object.getOwnPropertySymbols 方法来进行获取遍历
let id1 = Symbol("id1");
let id2 = Symbol("id2");
let obj = {
wid: 111,
[id1]: 'aaa',
[id2]: 'bbb'
};
let array = Object.getOwnPropertySymbols(obj);
console.log(array); // [ Symbol(id1), Symbol(id2) ]
console.log(obj[array[0]]); // aaa
其他 API
Symbol.for()
也时候我们需要多次使用同一个symbol值的情况,就可使用这个方法
通过这种方法就可以通过参数值获取到全局的symbol对象;
let name1 = Symbol.for('name'); //检测到未创建后新建
let name2 = Symbol.for('name'); //检测到已创建后返回
console.log(name1 === name2); // true
Symbol.keyFor()
通过symbol对象获取到参数,使用Symbol.keyFor()
let name1 = Symbol.for('name');
let name2 = Symbol.for('name');
console.log(Symbol.keyFor(name1)); // 'name'
console.log(Symbol.keyFor(name2)); // 'name'
BigInt(ES6 新增数据类型)
基本定义
BigInt 是一种特殊的数字类型,它提供了对任意长度整数的支持。
创建 bigint 的方式有两种:在一个整数字面量后面加 n 或者调用 BigInt 函数。
console.log(90099999999999992 === 90099999999999993); // true
console.log(90099999999999992n === 90099999999999993n); // false
console.log(BigInt("90099999999999992") === BigInt("90099999999999993")); // false
相关文章
bigInt 解决了什么问题,适用于那些场景?
复杂数据类型
Object
目前为止,大多数引用值的示例使用的是 Object 类型。Object 是 ECMAScript 中最常用的类型之一。虽然 Object 的实例没有多少功能,但是很适合存储和在应用程序间交换数据。
显示的创建Object 有两种方式
-
使用 new 操作符和 Object 构造函数
function myNew(Con, ...args) { // 创建一个新的空对象 let obj = {}; // 将这个空对象的__proto__指向构造函数的原型 // obj.__proto__ = Con.prototype; Object.setPrototypeOf(obj, Con.prototype); // 将this指向空对象 let res = Con.apply(obj, args); // 对构造函数返回值做判断,然后返回对应的值 return res instanceof Object ? res : obj; } -
使用对象字面量表示
Array
创建方式
- 使用 Array 构造函数
- 使用数组字面量
检测数组
- instanceof
-
- 使用 instanceof 的问题是是假定只有一个全局执行上下文。如果页面中有多个框架(比如 iframe),则可能涉及两个不同的全局执行上下文,因此就会有两个不同版本的 Array 构造函数。
- Array.isArray
-
- 这个方法用来确定一个值是否是数组,而不用管它是在哪个全局执行上下文中创建的
相关API
迭代器方法
- keys()
- values()
- entries()
复制和填充方法
- fill()
- copyWith()
转换方法
- toLocalString()
- toString()
- valueOf()
栈方法
- push()
- pop()
队列方法
- shift(): 删除数组第一项并返回它,数组长度减1
- unshfit():向数组开头添加任意多个值,并返回新的数组长度。
排序方法
- reverse()
- sort()
操作方法
- concat()
- slice()
- splice()
搜索和位置方法
严格相等
- indexOf()
- lastIndexOf()
- includes()
断言函数
允许按照定义的断言函数搜索数组,每个索引都会调用这个函数
- find()
- findIndex()
迭代方法
- every()
- filter()
- forEach()
- map()
- some()
归并方法
- reduce()
- reduceRight()
Function
Map
Set
WeakSet
WeakMap
Map、Set、WeakMap、WeakSet 见后续文章