🎄

ENCA 17日目: catch 束縛変数とそのブロック内の for...of 内の var による変数名重複の許容

2024/12/18に公開

try 文の Static Semantics: Early Errors

try 文の Static Semantics: Early Errorscatch によって束縛された変数と、その後続のブロック内で変数名が重複したとき SyntaxError となる記述がなされています。

// SyntaxError
try {} catch (e) { const e; }

しかし var によって変数宣言されているときにも SyntaxError としてしまうと ES5.1 以前との互換性を壊してしまうこととなってしまいます。というわけで Annex B VariableStatements in Catch Blocks にてその部分のセマンティクスを上書きする形で var の場合は許容するように定義されています。

// Annex B で許される(非ブラウザランタイムでは SyntaxError にするのが望ましい)
try {} catch (e) { var e; }

詳しくは Masaki Hara さんの記事の「catch変数の重複判定の緩和」を参考にしてください。

https://zenn.dev/qnighy/articles/1d96f2c0c662f6#catch変数の重複判定の緩和

catch 束縛変数とそのブロック内の for...of 内の var による変数名重複の許容

catch の束縛変数と、その後続するブロック内の for...of 内var による変数名が重複したときのことを考えます。

try {} catch (e) { for (var e of whatever) {} }

for...of は ES2015 から導入されたこともあり、これは ES5.1 で書かれたコードの互換性を壊さないことから Annex B であっても SyntaxError として扱われていました。

さて仕様ではそうなっていますが実際の JavaScript エンジンの実装では V8 と SpiderMonkey は SyntaxError となり、JavaScriptCore ではソースコード内に FIXME コメントが付いたままの状態で素通りするようになっていました。しかしこれをわざわざ実装したところで喜ぶ Web ディベロッパーはいなさそうです。

この仕様は変に実装を複雑にしてしまっているということで議論され、2019年1月にこの重複を許容する変更が承認されました。

https://github.com/tc39/ecma262/pull/1393

Discussion