我决定尝试使用 javascript 中的生成器,并发现了奇怪的(对我来说)行为。我个人并不完全清楚yield的执行顺序。
让我们看一下这段代码:
function* gen() {
return yield yield 5;
}
const iter = gen();
console.log(iter.next()); // value = 5
console.log(iter.next(2)); // value = 2
console.log(iter.next(3)); // value = 3
原则上,最右边的yield首先执行是合乎逻辑的,并且它们的顺序与堆栈的顺序相同。
但我们以下面的代码为例:
function* gen() {
return (yield) + (yield) - (yield);
}
const iter = gen();
console.log(iter.next()); // value = undefined
console.log(iter.next(2)); // value = undefined
console.log(iter.next(4)); // value = undefined
console.log(iter.next(7)); // value = -1
// Вот как получилось -1: 2 + 4 - 7 = -1
由于某种原因,添加括号和运算符可以使顺序保持一致。
这是下一个例子:
function* gen() {
return yield (yield) - (yield);
}
const iter = gen();
console.log(iter.next()); // value = undefined,
console.log(iter.next(3)); // value = undefined,
console.log(iter.next(6)); // value = -3,
console.log(iter.next(7)); // value = 7,
// Вот как получилось -3: 3 - 6 = -3
// А 7 просто подставилось
但在这个例子中,yield 触发顺序是 2,3,1。
为什么顺序是这样的,文档或标准中是否有描述?如果没有描述,那么阅读您对触发什么原则收益率的看法会很有趣
我们查看运算符优先级表,发现
yield要么是一元运算符,要么根本没有操作数。它的优先级是最低的之一,仅低于逗号运算符。1
yield yield 5编译为yield (yield 5).左边的表达式yield使用括号中的表达式,必须首先对其求值。顺序是从右到左。2
(yield) + (yield) - (yield)更狡猾一点。它周围的括号yield使其成为无参数运算符,可以表示为(yield undefined) + (yield undefined) - (yield undefined)。正负链是从左到右计算的。也就是说,yield它们将从左到右被调用。3
yield (yield) - (yield)编译为yield ((yield) - (yield)), 的yield优先级低于-.左边的yield使用差异作为参数。必须首先计算差值。差异参数是从左到右计算的。