集合类对象✅
Iterator 的概念与作用
答案
Iterator(迭代器)是一种为各种不同数据结构提供统一访问机制的接口。它的作用有三点:1)为各种数据结构提供统一、简便的访问接口;2)使数据结构的成员能够按某种次序排列;3)支持 for...of 等新的遍历命令。
迭代器对象通过 next()
方法依次返回集合成员,每次返回 { value, done }
,其中 done
表示遍历是否结束。
只要数据结构部署了 Symbol.iterator
方法,就可以用 for...of 遍历。
const arr = ['a', 'b', 'c']
const iter = arr[Symbol.iterator]()
console.log(iter.next()) // { value: 'a', done: false }
console.log(iter.next()) // { value: 'b', done: false }
console.log(iter.next()) // { value: 'c', done: false }
console.log(iter.next()) // { value: undefined, done: true }
答案解析
Iterator 让不同数据结构都能用统一方式遍历,极大提升了 JS 的可扩展性和一致性。
面试官视角
- 核心考察点:能否准确描述 Iterator 的作用和基本用法
- 评分标准:
- 差:只会用 for...of,不知其原理
- 良:能说出 next()、value、done
- 优:能举例说明并解释统一遍历机制
哪些数据结构原生支持 Iterator?如何自定义?
答案
原生支持 Iterator 的数据结构有:数组、字符串、Set、Map、类数组对象(如 arguments、NodeList)。
普通对象默认不支持,但可以通过实现 Symbol.iterator
方法自定义。
const obj = {
* [Symbol.iterator] () {
yield 1
yield 2
}
}
for (const v of obj) {
console.log(v) // 1, 2
}
答案解析
掌握哪些结构可直接 for...of,能自定义 Symbol.iterator 是进阶能力。
面试官视角
- 核心考察点:能否区分原生支持与自定义
- 评分标准:
- 差:只会遍历数组
- 良:能说出 Set/Map 支持
- 优:能写出自定义 iterator
Iterator 接口会在什么场合被自动调用?
答案
自动调用 Iterator 接口的场合有:
- for...of 循环
- 解构赋值(如
[a, b] = set
) - 扩展运算符(
...
) - yield* 表达式
- Array.from、Promise.all、Map/Set 构造等
const set = new Set(['a', 'b', 'c'])
const [x, y] = set
console.log(x, y) // a b
console.log([...set]) // ['a', 'b', 'c']
答案解析
理解这些场合有助于写出更简洁的代码。
面试官视角
- 核心考察点:能否列举常见自动调用场景
- 评分标准:
- 差:只知道 for...of
- 良:能说出解构、扩展运算符
- 优:能举例说明
Set 和 Map 的底层实现及时间复杂度?
答案
Set 和 Map 通常基于哈希表(HashMap)实现,查找、插入、删除操作平均时间复杂度 O(1)。
哈希冲突严重时最坏可退化为 O(n)。
答案解析
理解底层实现有助于合理选择数据结构和优化性能。
面试官视角
- 核心考察点:能否说出哈希表原理和复杂度
- 评分标准:
- 差:只会用不会分析
- 良:能说出 O(1)
- 优:能说明哈希冲突和最坏情况
Map 和 WeakMap、Set 和 WeakSet 有什么区别?
答案
- Map/Set:键可以是任意类型,强引用,支持遍历和 size。
- WeakMap/WeakSet:键只能是对象,弱引用,不可遍历,无 size。
- 弱引用:如果对象没有其他引用,垃圾回收时会自动移除 WeakMap/WeakSet 中的键值对,防止内存泄漏。
答案解析
WeakMap/WeakSet 适合做缓存、私有数据存储,避免内存泄漏。
面试官视角
- 核心考察点:能否说出弱引用和应用场景
- 评分标准:
- 差:只会用 Map/Set
- 良:能说出 WeakMap/WeakSet 特点
- 优:能举例说明弱引用用途
如何遍历 Map?有哪些常用 API?
答案
for...of
遍历键值对forEach
遍历keys()
、values()
、entries()
返回对应的迭代器- 扩展运算符
[...map]
转数组
const map = new Map([['a', 1], ['b', 2]])
for (const [k, v] of map) { console.log(k, v) }
map.forEach((v, k) => console.log(k, v))
console.log([...map.keys()]) // ['a', 'b']
答案解析
掌握多种遍历方式,灵活应对不同需求。
面试官视角
- 核心考察点:能否熟练遍历 Map
- 评分标准:
- 差:只会 for...of
- 良:能用 forEach/keys
- 优:能用扩展运算符
WeakMap/WeakSet 的典型应用场景?
答案
WeakMap/WeakSet 适合存储对象的私有数据、缓存、元数据等场景。
当对象被销毁时,相关数据会自动被垃圾回收,避免内存泄漏。
const wm = new WeakMap()
let obj = {}
wm.set(obj, 'private')
obj = null // 对象被销毁,WeakMap 自动清理
答案解析
理解弱引用的自动回收机制,能写出健壮的缓存和私有数据方案。
面试官视角
- 核心考察点:能否举例说明 WeakMap/WeakSet 用途
- 评分标准:
- 差:只会用 Map
- 良:能说出缓存用途
- 优:能结合内存管理说明