Зарезервированные ключевые слова не могут использоваться как идентификаторы (имена переменных) .В отличие от большинства других специальных слов Javascript (например, перечисленных в вопросе, let
, finally
, ...), await
является , а не зарезервированным ключевым словом, поэтому использование его в качестве имени переменной делаетне выбрасывать синтаксическую ошибку.Почему это не было превращено в зарезервированное ключевое слово, когда вышел новый синтаксис?
Обратная совместимость
В 2011 году, когда ES5 был еще относительно новым, код, который использовал await
(и async
), поскольку имена переменных были совершенно правильными, поэтому вы могли видеть что-то подобное на нескольких сайтах:
function timeout(ms) {
var await = $.Deferred();
setTimeout(await.resolve, ms);
return await.promise();
};
Выбор этого имени переменной может показаться странным, но ничего не было неправильно с этим.await
и async
никогда не были зарезервированными ключевыми словами - если авторы спецификации ES2017 превратили await
в зарезервированное ключевое слово, и браузеры реализовали это изменение, люди, посещающие эти старые сайты в более новых браузерах, не смогут использовать их.места;они, скорее всего, будут сломаны.
Так что, возможно, если бы они были превращены в зарезервированные ключевые слова, несколько сайтов, которые выбрали бы своеобразное имя переменной, не работали бы должным образом - почему существование этих сайтов должно существоватьнавсегда повлияет на будущее развитие ECMAscript и приведет к запутанному коду, как в вопросе?
Поскольку браузеры откажутся реализовать функцию, которая нарушает работу существующих сайтов. Если пользователь обнаружит, что сайт делаетне работает на одном браузере, но работает на другом, что будет стимулировать их к переключению браузеров - создатель первого браузера не хотел бы этого, потому что это означало бы меньшую долю рынка для них, даже если эта функция делает язык болеепоследовательный и понятный.Кроме того, редакторы спецификации не хотят добавлять что-то, что никогда не будет реализовано (или будет реализовано только время от времени), потому что тогда спецификация утратит часть своего статуса как стандарта - вопреки своей основной цели.
Вы могли видеть эти взаимодействия в действии с Array.prototype.flatten
и Array.prototype.contains
- когда браузеры начали их отправку, было обнаружено, что они сломали несколько существующих сайтов из-законфликты имен, поэтому браузеры отказались от реализации, и спецификацию пришлось настроить (методы были переименованы в .flat
и .includes
).
На самом деле - это ситуация, в которой await
не может использоваться в качестве идентификатора, который находится внутри модулей ES6:
<script type="module">
const await = 'Does it work?';
</script>
Это связано с тем, что в то время как модули ES6 (ES2015) находились в процессе разработки, async
/ await
уже была на горизонте ( начальная фиксация для async
/ await
предложение можно увидеть в начале 2014 года), поэтому при разработке модулей await
можно было бы сделать зарезервированным ключевым словом при подготовке к будущему, не нарушая ни одного из существующих сайтов.
Относительно первого фрагмента в вопросе:
const foo = await /barbaz/
myFn()
Это синтаксически допустимо, поскольку await
является допустимым именем переменной вне async
функций, и интерпретатор считает, что вы пытаетесь делить вместо использования регулярного выражения:
const foo = await / barbaz / myFn()
Если не использовать автоматическую вставку точек с запятой, можно было бы выявить проблему раньше, поскольку последний /
не мог быть интерпретирован как деление:
const foo = await /barbaz/;
myFn();
Эта довольно неоднозначная ситуация была фактически специально поднята на заседании ТК39 на async
/ await
:
YK: Что вас беспокоит?
WH: Неопределенности в последовательностях кода, которые начинаются с await /, а затем интерпретируются различными способами (из-заИдентификатор await-as-identifier против разграничения await-as-operator, который переворачивает / между делением и началом регулярного выражения) по грамматикам покрытия по сравнению с реальными грамматиками.Это потенциальная ошибка фермы.