【JavaScript】Identifierの構文エラー

# はじめに

前回に引き続き Identifier について学習ログ記事です。

https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#prod-IdentifierReference

# Identifierの構文エラー[^1]

[^1]: 「構文エラー」という章タイトルについて
ECMA公式ドキュメントでは"Early Errors"の項に記載されているものですが、"Early Error"が定義されておらず不明瞭かつ正確な役語が見つからないこと・実際に発生するエラーのすべてが"StntaxError"だったことから「構文エラー」という章タイトルにしています。
## `arguments` / `eval`

- 厳格モード（`strict mode`）かつ識別子名称が`arguments`もしくは`eval`
（`BindingIdentifier`のみ）

```js
"use strict";

//SyntaxError Unexpected eval or arguments in strict mode
const arguments = [];

//SyntaxError Unexpected eval or arguments in strict mode
function eval() {
  return '';
}
```

## `yield`

- 厳格モード（`strict mode`）かつ識別子名称が `yield`
（`IdentifierReference` / `BindingIdentifier` / `LabelIdentifier` すべて）

```js
"use strict";

//SyntaxError strict mode reserved word
const yield = ''; 

//SyntaxError strict mode reserved word ※ReferenceErrorではない
console.log(yield);

//SyntaxError strict mode reserved word
yield: {
  break yield;
}
```

参考：存在しない識別子へのアクセスは、通常`ReferenceError`になる
```js
//ReferenceError
console.log(obj);
```

- `yield` が特別な意味を持つ文脈（`Generator` など）で識別子名称が `yield`
（`BindingIdentifier` のみ）

```js
function* generator() {

  //SyntaxError Unexpected identifier 'yield'
  const yield = ''; 

  //SyntaxError Unexpected identifier 'yield' ※'-'が無い場合通常のyieldとして処理される
  console.log(-yield);

  //SyntaxError ※ただし、Unexpected token ':'
  yield: {
    break yield;
  }
  
}
```

## `await`

- `goal symbol` が `Module` かつ識別子名称が `await`
※`Module`の文脈では`strict mode`になる
※`goal symbol` は構文解析のエントリーポイント
（`IdentifierReference` / `BindingIdentifier` / `LabelIdentifier` すべて）

```html
<html>
  <!--head-->
  <body>
    <script type="module">
    
      //SyntaxError Unexpected identifier 'yield'
      const await = '';
      
      //SyntaxError Unexpected identifier 'yield' ※'-'が無い場合通常のyieldとして処理される
      console.log(await);
      
      //SyntaxError Unexpected identifier 'yield'
      await: {
        break await;
      }
    
    </script>
  </body>
</html>
```

- `awati` が特別な意味を持つ文脈（`async` 関数など）で識別子名称が `await`
（`IdentifierReference` / `BindingIdentifier` / `LabelIdentifier` すべて）

```js
async function func() {
  
  //SyntaxError Unexpected reserved word
  const await = ''; 

  //SyntaxError ※ただし、Unexpected token ')'
  console.log(await);

  //SyntaxError ※ただし、Unexpected token ':'
  await: {
    break await;
  }

}
```

## その他

- 厳格モード（`strict mode`）かつ識別子名称が `implements` / `interface` / `let` / `package` / `private` / `protected` / `public` / `static`
（`IdentifierReference` / `BindingIdentifier` / `LabelIdentifier` すべて）

```js
"use strict";

//SyntaxError strict mode reserved word
const implements = ''; 

//SyntaxError strict mode reserved word ※ReferenceErrorではない
console.log(implements);

//SyntaxError strict mode reserved word
implements: {
  break implements;
}
```

- 識別子名称が予約語に該当する時
（`IdentifierReference` / `BindingIdentifier` / `LabelIdentifier` すべて）


```js
//SyntaxError Unexpected token 'break'
const break = '';

//SyntaxError Unexpected token 'case'
console.log(case);

//SyntaxError Unexpected token 'catch'
catch: {
  break catch;
}
```

予約語についてはこちら

https://qiita.com/kohki_takatama/items/534bb8d0739d86157d9a