考虑一个函数query_item
,它返回一个要处理的对象,或null
,如果不再处理任何内容。
let item = query_item();
while(item !== null){
process(item);
item = query_item();
}
显然,这是对DRY的轻微违反(不要自己重复),大多通过将query_item()
作为专用功能来缓解。
我知道在这个简单的例子中,清晰度比防止重复要重要得多。
然而,是否有办法在不重复分配的情况下编写这样的循环?
我想出的唯一一个问题是for循环方法,但是它具有相同的重复性,并且 - 至少在我看来 - 有点难以阅读。
for(let item = query_item();
item !== null;
item = query_item()
){
process(item);
};
答案 0 :(得分:3)
这是标准情况,人们可以在while
条件中使用分配:
let item;
while (item = query_item()) {
process(item);
}
或者可能,如果你想要明确:
let item;
while ((item = query_item()) !== null) {
process(item);
}
您也可以使用相同方法的for
循环,这也为let
提供了阻止范围:
for (let item; item = query_item(); ) {
process(item);
}
答案 1 :(得分:0)
小巧漂亮?
let item;
do {
item = query_item();
if (item) process(item);
} while (item !== null)
答案 2 :(得分:0)
如果你想完全避免这种赋值怪异并获得最简单的循环语法,你可以考虑使用ES6 iterator:
function query_items() {
return {
[Symbol.iterator]() {
return this;
},
next() {
return {
value: query_item(),
get done() { return this.value === null }
};
}
};
}
for (let item of query_items()) {
process(item);
}
或者甚至可以立即更好地query_items
作为generator function。
答案 3 :(得分:0)
assignment within the loop condition ...
的替代方案let item;
while (item = query_item()) {
process(item);
}
...是generator function,在遇到null
值后终止:
function* iterate(cb) {
let next = cb();
if (next === null) return;
yield next, yield* iterate(cb);
}
for (let item of iterate(query_item)) {
process(item);
}
答案 4 :(得分:-1)
对于javascript我相信你可以写:
while(let item = query_item() && item){
process(item);
}