Reserved keywords cannot be used as identifiers (variable names). Unlike most other special Javascript words (like those listed in the question, let
, finally
, ...), await
is not a reserved keyword, so using it as a variable name does not throw a SyntaxError. Why wasn't it made into a reserved keyword when the new syntax came out?
Backwards compatibility
Back in 2011, when ES5 was still a relatively new thing, code that used await
(and async
) as variable names was perfectly valid, so you may have seen something like this on a couple sites:
function timeout(ms) {
var await = $.Deferred();
setTimeout(await.resolve, ms);
return await.promise();
};
The choice of that variable name may seem odd, but there was nothing wrong with it. await
and async
have never been reserved keywords - if the writers of the ES2017 specification made await
into a reserved keyword, and browsers implemented that change, people visiting those older sites on newer browsers would not be able to use those sites; they would likely be broken.
So perhaps if they were made into reserved keywords, a few sites which chose a peculiar variable name wouldn't work properly - why should the existence of those sites permanently affect the future evolution of ECMAscript and result in confusing code like in the question?
Because browsers will refuse to implement a feature which breaks existing sites. If a user finds that a site does not work on one browser, but works on another, that will incentivize them to switch browsers - the maker of the first browser would not want that, because that would mean less market share for them, even if it's a feature which makes the language more consistent and understandable. In addition, the editors of the specification do not want to add something that will never be implemented (or will only be implemented sporadically), because then the specification would lose some of its status as a standard - contrary to its main goal.
You could see these interactions in action with Array.prototype.flatten
and Array.prototype.contains
- when browsers started shipping them, it was found that they broke a few existing sites due to name conflicts, so the browsers backed out of the implementation, and the specification had to be tweaked (the methods were renamed to .flat
and .includes
).
There actually is a situation in which await
cannot be used as an identifier, which is inside of ES6 modules:
<script type="module">
const await = 'Does it work?';
</script>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…