ECMAScriptの第一歩

## はじめに

この記事はHRBrain Advent Calendar 2022の17日目の記事です。

https://qiita.com/advent-calendar/2022/hrbrain

株式会社HRBrainでフロントエンドエンジニアインターンをしている、若槙です。

この記事では、ECMAScriptの仕様について、いいとこ取りでまとめていきます。

## ECMAScriptとはそもそも何か？

>ECMAScript is based on several originating technologies, the most well->known being JavaScript (Netscape) and JScript (Microsoft). 
>
>>日本語訳
>ECMAScriptはいくつかの起源となる技術をベースにしていますが、最もよく知られているのはJavaScript(Netscape)とJScript(Microsoft)です。

出典：https://www.ecma-international.org/publications-and-standards/standards/ecma-262/

***ECMAScript***は、JavaScriptから生まれ、JavaScriptの仕様を定義したものです。
***ECMAScript***が誕生する前は、Netscape社のJavaScriptと、Microsoft社のJScript(広義でのJavaScript)で、それぞれ違う仕様かつ、その他ブラウザ毎に仕様の異なるJavaScriptが乱立している状態でした。
この問題を解決するため、Netscape社は、国際規格策定団体[ECMA International](https://www.ecma-international.org/)にJavaScriptの標準化を依頼しました。***ECMA International***によって標準化されたJavaScriptは、***ECMAScript***と呼ばれることになりました。

## LivingStandardなECMAScript

現在、ECMAScriptの仕様書のドラフトはGitHub上の[tc39/ecma262](https://github.com/tc39/ecma262)で管理され日々更新されています。実際にJavaScriptとして実装される際にも、**LivingStandard**のECMAScriptを参照しています。
このように、更新ごとにバージョン番号をつけず、常に最新版が公開されているものを**LivingStandard**と呼びます。

## プロポーザル方式
### プロポーザル方式って？
仕様に追加する機能（API、構文など）をそれぞれ個別のプロポーザル（提案書）として進めており、それぞれのプロポーザルは責任者である**チャンピオン**と、**ステージ**とよばれる5段階(0~4)のいずれかの状態を持ちます。
プロポーザルは、2か月に一度、TC39のミーティングで議論され、ステージ4になったプロポーザルは[tc39/ecma262](https://github.com/tc39/ecma262)にマージされ、`ECMAScript20☓☓`としてリリースされます。
![スクリーンショット 2022-12-07 11.42.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1958304/074bbe6b-06bb-0382-c9bc-c99cccbc56dc.png)
現在策定中のプロポーザルは、GitHub上の[tc39/proposals](https://github.com/tc39/proposals)に一覧が公開されています。

### プロポーザル方式の採用背景
`ES2015`以前はすべての仕様の合意が取れてからのリリースでした。
それでは時間があまりにかかりすぎるということで……
`ES2016`以降からTC39は毎年リリースするためにECMAScriptの策定プロセスをプロポーザル方式に変更しました。

## ESLint

`ES20XX`では様々な機能や文法が取り入れられています。
それにあわせてコーディングも`ES20XX`のルールに従って記述していく必要があります。
このような場合に便利なのが**ESLint**です。
**ESLint**はJavaScriptのための静的解析ツールです。**ESLint**を使用することで、スタイルガイドラインに準拠していないコードを発見できるなどの恩恵を受けることができます。
なにより、独自でルールをカスタマイズできるのが最大の特徴と言えます。

## JIS規格

ECMAScriptは**JIS X 3060**として、**JIS化**されています。
英語が辛いという方は、JIS化されたものを参考にしてみては、いかがでしょうか。

:::note info
JIS規格のECMAScriptを閲覧できるページ
[日本規格協会](https://webdesk.jsa.or.jp/books/W11M0090/index/?bunsyo_id=JIS+X+3060%3A2000)
[日本産業標準調査会](https://www.jisc.go.jp/app/jis/general/GnrJISNumberNameSearchList?toGnrJISStandardDetailList&jisStdId=2100039171&jisStdNo=X3060)
:::



![スクリーンショット 2022-12-07 11.58.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1958304/1aee3c7a-d268-14d5-c841-db027947d55b.png)
2000年4月に制定された時から改正はまだされていないですね……

### JISX3060とECMA-262を比較（ECMA-262の4章まで）

すべてを網羅して読めた訳ではないので、参考までに……

|  　| JISX3060 | ECMA-262 | 
|:-----------|------------:|:------------:|
| 厳密なバリエーション(Strict Mode)       | 記載なし        | 記載あり         |
| 組み込みオブジェクト     | Global, Function, Boolean, Array, String, BooleanObject, Number, Math, Dateオブジェクトがあるという紹介のみ      | RegExp, JSON, ArrayBuffer, SharedArrayBuffer, DataView, Promise, Proxy, Reflectオブジェクトが追加され、それぞれのオブジェクトについての簡易的なコメントもある     |

### 差分が生じている理由
ECMAScriptには、***デファクト標準***(Ecma Internationalにより標準化されたもの)と***デジュール標準***(ISOが標準化したもの [ISO/IEC 16262](https://www.iso.org/standard/55755.html))があります。基本的に参照しているのは、***デファクト標準***です。
JISX3060は、`ECMA-262 Edition 3`の仕様書の最初の章の概要を日本語訳しているだけで、その他の残りの章は`ISO/IEC 16262:1998`を引用しています。
つまり、JISX3060は古い`ECMA-262`を参照したまま、未だ改正を行っていないため、差分が生じているわけです。

>**参考URL**
竹迫良範、2013、ECMA-262 Edition 5.1を読む、https://www.ecma262.info/#:~:text=Q.%20ECMA%2D262,%E3%81%93%E3%81%A8%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82


## Tips(ES2022で追加された機能の一部を紹介)

`ES2022`のこれ明日から使えそうだと思った機能を一部、紹介します。

### Array, String, TypedArray の .at()

```js
const array = ["鎌田", "久保", "南野", "堂安"];

console.log(array[1]); // "久保"

// ES2022
console.log(array.at(1); // "久保"

// 従来の配列末尾からの参照
console.log(array[array.length - 1]); // "堂安"

// ES2022で可能になる書き方
console.log(array.at(-1)); // "堂安"
```

### Error.cause

`Error`のコンストラクタの第二引数にオプションとして`cause`を与えることで、どこで例外が発生したかを特定できるようになります。
これだけの仕様なら`Error`を継承したカスタムエラーで再現することも可能です。ではなぜ、`Error.cause`を標準化する必要があったのでしょうか。
それは`cause`プロパティを標準仕様として規定することにより、デバッグツールなどでエラーチェインを扱えるようにするためです。実際に、`Error.cause`のプロポーザルでも以下のように記載されています。
>**Why not custom subclasses of Error**
While there are lots of ways to achieve the behavior of the proposal, if the cause property is explicitly defined by the language, debug tooling can reliably use this info rather than contracting with developers to construct an error properly.

#### ES2022～

```jsx
async function doJob() {
  const rawResource = await fetch('//domain/resource-a')
    .catch(err => {
      throw new Error('Download raw resource failed', { cause: err });
    });
  const jobResult = doComputationalHeavyJob(rawResource);
  await fetch('//domain/upload', { method: 'POST', body: jobResult })
    .catch(err => {
      throw new Error('Upload job result failed', { cause: err });
    });
}

try {
  await doJob();
} catch (e) {
  console.log(e);
  console.log('Caused by', e.cause);
}
// Error: Upload job result failed
// Caused by TypeError: Failed to fetch
```


## まとめ

ECMAScriptの仕様について説明しました。
座学的な勉強も、言語に対する愛着を持つという点では、結構ありですね。
私自身、jQueryから、JavaScriptすっとばして、Reactを今メインで書いているのですが、もうちょっとJavaScriptのことも関心持ってあげようと思います。



## 最後に

株式会社HRBrainでは新しいメンバーを募集中です。

https://www.hrbrain.co.jp