values方法返回arrayiterator对象,仅支持单向顺序遍历,不可随机索引、无length属性,需手动调用next()按需取值,适合for...of等流式消费场景。

values 方法返回的是迭代器,不是数组
调用 Array.prototype.values() 不会得到一个可随机索引的数组,而是返回一个 ArrayIterator 对象——它只支持按顺序、单向、一次性的遍历。常见错误是写成 arr.values()[0] 或试图用 length 获取长度,结果是 undefined 或报错。
- 迭代器没有
length、map、push等数组方法 - 不能用方括号下标访问(
it[0]无效) - 多次调用
.next()才能逐步取值,且不可回退 - 一旦遍历完毕,再次调用
.next()总是返回{value: undefined, done: true}
按需访问必须手动调用 next(),不能跳索引
所谓“按需”,是指你控制何时取下一个值,但无法直接跳到第 5 个元素。想拿到第 n 个元素,只能循环调用 next() n+1 次(从 0 开始计数),中间无法跳过。
const arr = ['a', 'b', 'c', 'd'];
const it = arr.values();
<p>// 想取第 2 个元素('c'),得这样:
it.next(); // {value: 'a', done: false}
it.next(); // {value: 'b', done: false}
const third = it.next(); // {value: 'c', done: false}
console.log(third.value); // 'c'</p>
- 没有类似
it.get(2)或it.seek(2)的方法 - 若需随机访问,应直接用原数组下标:
arr[2];values()不适合该场景 - 如果只是想“延迟计算”,但后续仍需频繁索引,不如用生成器函数封装逻辑
转成数组后就失去“按需”特性,慎用 Array.from
有人用 Array.from(arr.values()) 把迭代器转成数组,以为能“先获取再操作”。这确实能得到数组,但代价是:一次性消耗整个迭代器,所有元素立即被读取并存入内存——完全违背“按需访问”的初衷。
-
Array.from(arr.values())和[...arr.values()]效果相同,都是立即展开 - 对大数组或异步生成的迭代器(如自定义迭代器返回 Promise),这种转换会阻塞并吃内存
- 若真需要部分元素,更稳妥的方式是写个辅助函数,只调用指定次数的
next()
真正适合 values + 按需的典型场景
适合 values() 的地方,是明确知道要逐个处理、且不回头、不跳步的流程,比如配合 for...of、yield* 或流式消费逻辑。
function* takeFirstN(iter, n) {
let i = 0;
for (const v of iter) {
if (i >= n) break;
yield v;
i++;
}
}
<p>const arr = [10, 20, 30, 40, 50];
const it = arr.values();
for (const x of takeFirstN(it, 3)) {
console.log(x); // 10, 20, 30 —— 真正按需、不浪费
}</p>
-
for...of内部自动调用next(),最自然的按需方式 - 与
break/return配合,能提前终止,避免多余计算 - 嵌套在生成器中时,
yield*可直接委托迭代,保持惰性
别为了“看起来高级”而用 values(),它解决的不是“怎么取第几个”,而是“怎么不一口气全拿”。真正需要索引访问时,原生数组下标永远更快、更直接。










