/
は、さまざまなキーワードと演算子の周囲で解釈され、次の構文が完全に合法であることがわかりました。
// awaiting something that isn't a Promise is fine, it's just strange to do:
const foo = await /barbaz/
myFn()
エラー:
キャッチされていないReferenceError:awaitが定義されていません
await
を変数名 ..?として解析しようとしているようです。私は期待していました
awaitは非同期関数でのみ有効です
または多分何か
予期しないトークンが待機しています
恐ろしいことに、それに物事を割り当てることもできます。
const await = 'Wait, this actually works?';
console.log(await);
let
、finally
、break
などの場合のように、明らかに間違ったものは構文エラーの原因になりませんか?なぜこれが許可され、最初のスニペットで一体何が起こっているのですか?
予約済みキーワードは 識別子(変数名) として使用できません。他のほとんどの特別なJavascript単語(質問にリストされているようなlet
、finally
、...)とは異なり、await
はではありません予約済みキーワードなので、変数名として使用してもSyntaxErrorはスローされません。新しい構文が出てきたのに、なぜそれが予約キーワードにされなかったのですか?
2011年にES5がまだ比較的新しいものであったときに、変数名としてawait
(およびasync
)を使用したコードは完全に有効だったので、いくつかのサイトでこのようなものを見たかもしれません:
function timeout(ms) {
var await = $.Deferred();
setTimeout(await.resolve, ms);
return await.promise();
};
その変数名の選択は奇妙に思えるかもしれませんが、それには間違ったはありませんでした。 await
とasync
が予約済みのキーワードになったことはありません-ES2017仕様の作成者がawait
を予約済みのキーワードにして、ブラウザーがその変更を実装した場合、新しいブラウザはこれらのサイトを使用できません。それらはおそらく壊れます。
したがって、予約済みのキーワードにした場合、特異な変数名を選択したfewサイトは適切に機能しません。これらのサイトの存在が、 ECMAscriptを使用すると、質問のようにコードが混乱しますか?
ブラウザは既存のサイトを破壊する機能の実装を拒否するためです。サイトが1つのブラウザでは機能しないが別のブラウザでは機能することが判明した場合、これは、ブラウザを切り替えることを奨励します-最初のブラウザのメーカーはそれを望まないでしょう。それは、言語をより一貫して理解しやすくする機能であっても、市場シェアが減少することを意味します。さらに、仕様の編集者は、決して実装されない(または散発的にのみ実装される)ものを追加することを望まないでしょう。仕様が標準としてのステータスの一部を失うことになるためです。
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
関数の外では有効な変数名であり、インタプリタはdivideではなく、正規表現を使用するより:
const foo = await / barbaz / myFn()
セミコロンの自動挿入に依存しない場合は、最後の/
は除算として解釈できませんでした:
const foo = await /barbaz/;
myFn();
この正確なややあいまいな状況は、実際にasync
/await
の- TC39ミーティング で具体的に取り上げられました。
YK:何が心配ですか?
WH:await /で始まり、その後、異なる方法で解釈されるコードシーケンスのあいまいさ(await-as-identifierとawait-as-が原因で)除算と正規表現の開始の間の/を反転する演算子の区別)カバー文法と実際の文法の比較。それは潜在的なバグファームです。