6 集合引用类型
6.1 Object
详见第八章。
1、创建对象
- 使用 new 和 Object 构造函数
- 对象字面量
// 1、构造函数
const person = new Object()
person.name = 'osmium'
person.age = 18
// 2、对象字面量
const person = {
name: 'osmium',
age: 18,
5: 2 // 数值属性会被转化为字符串
}
两种方式相同,只是后者不会去调用 Object 构造函数,开发者也更偏向于后者,因为这样代码量更少并且更加直观。
2、对象取值
- 点语法
- 中括号
// 1、点语法
person.name
// 2、中括号
person["name"]
const nm = "name"
person[nm]
person["first name"]
中括号语法更具有优势,可以通过变量访问属性
另外,中括号语法可以访问属性名可能导致语法错误的字符、关键字、保留字,如上带空格的属性
6.2 Array
和其他语言一样,ECMAScript 数组是一组有序的数据;动态大小,随着数据添加而增长。
不一样的是,每个元素可以是任意类型的数据。
1、 创建数组
- 构造函数
- 数组字面量
// 1、构造函数
const colors = new Array()
const colors = new Array("red", "yellow") // 创建包含 2 个元素的数组
const colors = new Array(2) // 创建一个初始长度为 2 的数组
const colors = Array(3) // 使用 Array 构造函数时,可省略 new 操作符
// 2、数组字面量
const colors = ["red", "yellow"]
ES6 新增的用于创建数组的静态方法 from() 和 of()
-
from():将类数组转化为数组
第一个参数是类数组(任何可迭代的结构,或者有一个 length 属性和可索引元素的结构)
第二个参数是可选的映射函数
-
of():将一组参数转化为数组
Array.from("hello") // ['h', 'e', 'l', 'l', 'o']
// 和 "hello".split('') 相同
// 将类数组转化为数组
const map = new Map().set("name", "osmium").set("age", 18)
const set = new Set().add(1).add(2)
Array.from(map) // [["name", "osmium"], ["age", 18]]
Array.from(set) // [1,2]
// 进行深拷贝
const nums = [1,2,3]
const nums2 = Array.from(nums)
nums === nums2 // false
// 映射函数
const a1 = [1, 2, 3, 4]
Array.from(a1, x => x*2) // [2, 4, 6, 8]
2、数组空位
由于行为不一致和存在性能隐患,实践中要避免使用数组空位
const arr = [1,,,4] // [1, undefined, undefined, 4]
3、数组索引
通过中括号里的数字索引
4、检测数组
const nums = [1, 2, 3]
nums instanceof Array
Array.isArray(nums)
5、迭代器方法
ES6 中,Array 原型上暴露了 3 个 用于检索数组内容的方法:keys()、values()、entries()。
- keys():数组索引迭代器
- values():数组元素迭代器
- entries():索引 / 值对的迭代器
6、复制和填充方法
- copyWithin():批量复制方法
- fill(value, startIndex, endIndex):填充数组方法
const nums = [1, 2, 3, 4]
nums.fill(9) // [9, 9, 9, 9]
7、转换方法
const colors = ['red', undefined, 'yellow']
colors.toString() // red,,yellow
colors.toLocaleString() // red,,yellow
colors.valueOf() // ['red', undefined, 'yellow']
8、栈方法
后进先出(LIFO):push、pop
9、队列方法
先进先出(FIFO):push、shift
10、排序方法
- reverse():反转
- sort(fn()):默认升序,每项都会调用 String() 转型函数,故对数字排序会出现问题,所以 sort() 方法接收一个比较函数
11、操作方法
- contact():拼接
- slice(startIndex, endIndex)
- splice(index, deleteCount, insertValue)
12、搜索和位置方法
- indexOf(value, startIndex)
- lastIndexOf(value, startIndex)
- includes(value)
- find():断言函数
13、迭代方法
- every()
- some()
- forEach()
- filter()
- map()
const nums = [1, 2, 3, 4]
nums.every(n => n > 2) // false
nums.some(n => n > 2) // true
14、归并方法
迭代数组的所有项,并在此基础上构建一个最终返回值。
- reduce()
- reduceRight()
6.3 定型数组
?
6.4 Map
ES6 新特性,一种新的集合类型,为这门语言带来了真正的键 / 值存储机制。
- size
- get(key)、set(key, value)、delete(key)、clear()
- has(key)
选择 Object 还是 Map
对象 or 映射
Object | Map | |
---|---|---|
内存占用 | 给定固定大小的内存,Map 可以比 Object 多存储 50% 的键/值对 | |
插入性能 | 稍微快一点 | |
查找速度 | 更好一些 | |
删除性能 | delete饱受诟病 | 更好一些 |
6.5 WeakMap
ES6新增,是一种新的集合类型,为这门语言带来了增强的键 / 值对存储机制。WeakMap 是 Map 的 ”兄弟“ 类型,其 API 也是 Map 的子集。Weak 描述的是 JavaScript 垃圾回收程序对待 ”弱映射“ 中键的方式。
- 键只能是 Object 或者继承自 Object 的类型(数组、函数、原始包装类型),值的类型没有限制
- 弱键:键值对任何时候都可能被销毁,所以不会提供迭代能力、也没有 clear() 这个一次性销毁所有键 / 值的方法
- 之所以只能使用对象作为键,是为了保证只有通过键对象的引用才能取得值
- 如果允许原始值,那就没办法区分 初始化时 和使用时是同一个了
实际应用
类:通过私用变量里的对象作为 WeakMap 的键,这样就避免在类之外,有一个和私有变量值相同的对象取到 WeakMap 里的值
6.6 Set
- size
- add()、delete()、clear()
- has()
6.7 WeakSet
值只能是 Object 或者继承自 Object 的类型(数组、函数、原始包装类型)
\