等待操作的运算符优先级是什么?

47
在JavaScript中,某些运算符在其他运算符之前进行处理:
1 + 2 * 3
// 1 + (2 * 3)
// 7 because * has higher precedence than +

1 === 0 + 1
// 1 === (0 + 1)
// true because + has a higher precedence than ===

MDN(Mozilla Developer Network)提供了所有操作符的完整排序列表,包括它们的优先级……但没有 await

await getFoo() * 2; // await (getFoo() * 2) or (await getFoo()) * 2?
await getFoo() === 5; // await (getFoo() === 5) or (await getFoo()) === 5?

(编辑: MDN现在已经包含await;当我最初写下这个问题时,它还没有。)

有人能解释一下在await之前/之后处理哪些运算符吗?

现在我感觉我不得不添加一堆可能不必要的括号,因为我不确定在await之前/之后会处理什么。而且虽然我知道我应该能够查找这个答案,但即使是MDN(我认为是文档的黄金标准)也没有答案。


1
有趣。await 期望在其后跟随一个表达式,但并未提供关于优先级如何处理的线索。是时候进行实验了。 - Nick
2
我的理解是,await 与任何一元运算符一样处理。 - raina77ow
1个回答

44

AwaitExpression 是一种 UnaryExpression,与 deletevoidtypeof+-~! 具有相同的优先级,比任何二元运算符都更强。

这与 yield 不同,后者的优先级低于除逗号运算符以外的所有内容。这个design decision是因为 yield a+bawait a + await b 这两种情况被认为比 (yield a) + (yield b)await (a + b) 更常见。


14
我也修复了 MDN :-) - Bergi
1
对于像 + 这样的运算符,这是很有意义的,然而,一个主要的陷阱是在使用 &&await 时。考虑 await url && fetch(url)。如果 url 在这里是假值,我们将短路并返回 url 的值(通常是 undefined)- 这是有意的 - 但如果它是真值,我们将继续调用 fetch(url),但表达式返回的是 promise 而不是 _resolved value_。你想要的可能是 await (url && fetch(url)) - JHH
2
然而,在大多数情况下,url && await fetch(url) 就足够了。 :) - JHH
2
@JHH 我通常基于原则避免在一般情况下await非thenable对象,因为这往往会产生难以阅读的代码,正如你所友善地展示的那样 ;) - Patrick Roberts
6
答案没有清楚地说明在 await 之前有哪些运算符。点(.)运算符的优先级高于 await。如果你有一个名为 func 的异步函数,它返回对象 {prop: 'str'},那么你需要写 (await func()).prop 才能正确获取属性,否则 await func().prop 将返回 undefined - Kutalia
1
@Kutalia 我不会在这个回答中重现完整的运算符表,但是成员访问是比一元运算符优先级更高的运算符之一。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接