6 集合引用类型

103 阅读4分钟

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 映射

ObjectMap
内存占用给定固定大小的内存,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 的类型(数组、函数、原始包装类型)

\