完整的ES6 Compatibility table。刚刚进入Set()
。
const set = new Set();
set.add('foo');
set.add('baz');
const iterator = set.values();
iterator.next(); // { value: "foo", done: false }
iterator.next(); // { value: "baz", done: false }
是否可以编写类似于iterator.next()
的方法,但它会向后迭代而不是向前迭代(即iterator.previous()
)?
答案 0 :(得分:3)
values()
返回一个迭代器对象,不可能向后迭代它们,因为JavaScript迭代器对象可能是无限的。例如,考虑一下
function * Counter() {
"use strict";
var i = 0;
while (1) {
yield i++;
}
}
现在,您可以使用Counter()
创建一个永远不会结束的迭代器。因此,通常情况下,倒退不是迭代器的选项。
如果您非常需要像backIterator这样的东西,那么您必须维护迭代器生成的值,然后根据next
调用来回移动。
答案 1 :(得分:0)
我担心没有JS方法可以做到这一点,但是没有人阻止你将变量中的先前值保存并从中读取。
答案 2 :(得分:0)
尽管您目前无法为迭代器提供类似于previous()
方法的next()
方法,但其他答案均不正确。您可以通过更改迭代器的next()
方法来向后遍历ES iteration protocol中的任何迭代。
真正的罪魁祸首是您需要确定是要迭代还是向后。当前,您不能同时执行两项操作,因为必须重写迭代器中的next()
方法才能使它向后工作。
继续使用Set
对象的示例,您可以覆盖values()
方法并提供自己的可迭代迭代器,如下所示:
const set = new Set();
set.add('foo');
set.add('baz');
const iterator = set.values();
console.log(iterator.next()); // { value: "foo", done: false }
console.log(iterator.next()); // { value: "baz", done: false }
set.values = function () {
const reversedContents = Array.from(this);
return {
[Symbol.iterator]() {
return this;
},
next() {
const isDone = reversedContents.length === 0;
return {
value: reversedContents.pop(),
done: isDone
};
}
};
}
const reverseIterator = set.values();
console.log(reverseIterator.next()); // { value: "baz", done: false }
console.log(reverseIterator.next()); // { value: "foo", done: false }
这是不理想的,因为它会从集合中创建一个数组以便从集合中获取最后一个元素。
答案 3 :(得分:0)
没有什么可以阻止您这样做的,例如,下面通过包装Set
。
您显然无法直接在previous()
上进行迭代,但是您可以手动调用它,也可以仅通过调用previous()
来切换方向,然后进行反向迭代。
values() {
const items = [...set.values()];
let index = -1;
return {
[Symbol.iterator]() {
return this;
},
next() {
var item = items[index + 1];
if (item) {
return {
value: item,
done: false
};
}
return { done: true };
},
previous() {
var item = items[index - 1];
if (item) {
return {
value: item,
done: false
};
}
return { done: true };
}
};
}