【JavaScript】ES2023の新機能が何故かいまさら追加されていた

[ES2023その2](https://qiita.com/rana_kualu/items/49c51f4002043b97c59a) / [ES2023](https://qiita.com/rana_kualu/items/84f66fe970f7feccf367) / [ES2022](https://qiita.com/rana_kualu/items/8bafecd760ae69cfac41) / [ES2021](https://qiita.com/rana_kualu/items/ae3297dd2974fcf047c4)


先日[ES2023では新機能が2個しかなかった](https://qiita.com/rana_kualu/items/84f66fe970f7feccf367)という話をしましたが、どういうわけか2023/01/30になってからES2023が[2個追加](https://github.com/tc39/proposals/commit/d2a5cf370e4a9dc8b0249ad8a8386cd1280db815)[されました](https://github.com/tc39/proposals/commit/ad4df8435f27f39eda26db3b940ae151980c8015)。
よくわかりませんが、どうやら[1月までは前年のES](https://github.com/tc39/proposals/commit/924fdd63a1c82be6b8cfb6b063c5f00aaddb24bc)になるみたいです。
なんで。

これらは[2023/01/30に行われたTC39ミーティング](https://github.com/tc39/agendas/blob/main/2023/01.md)で決定したようです。
他に[Intl.NumberFormat V3](https://github.com/tc39/proposal-intl-numberformat-v3)もStage4への議題に上がったみたいですが、こちらは却下されたみたいです。
なんでそんなふわふわな言及なのかってまだ[アジェンダしかない](https://github.com/tc39/agendas/tree/main)から詳しいことがわからねえんだよ。


# Finished Proposals

## [Change Array by copy](https://github.com/tc39/proposal-change-array-by-copy)

配列を破壊せずに操作するメソッドを追加します。

既存の配列操作メソッドは、変更後の値を返すと同時に元の値も変更してしまいます。

```js
const a = [2, 3, 1];

const b = a;
b[1] = 4;
console.table(b); // [2, 4, 1]
console.table(a); // [2, 4, 1] ← ？

const c = a.sort();
console.table(c); // [1, 2, 4]
console.table(a); // [1, 2, 4] ← ？？

const d = a.reverse();
console.table(d); // [4, 2, 1]
console.table(a); // [4, 2, 1] ← ？？？？
```

これはひどい。

おかげで毎回[Array.concat()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/concat)やら[Array.slice()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)やらの[不正な使用を強制させられる](https://zenn.dev/kou_pg_0131/articles/js-clone-array)という有様でした。

今回のProposalが通ったことで、ようやくまともに配列操作関数が扱えるようになります。

```js
const a = [2, 3, 1];

const b = a.with(1, 4);
console.table(b); // [2, 4, 1]
console.table(a); // [2, 3, 1]

const c = a.toSorted();
console.table(c); // [1, 2, 3]
console.table(a); // [2, 3, 1]

const d = a.toReversed();
console.table(d); // [1, 3, 2]
console.table(a); // [2, 3, 1]
```

なお、Chromeでは[Dev Trial 108](https://chromestatus.com/feature/5068609911521280)でようやく使えるようになっただけで通常版リリースはいまだ未定、Firefoxも[実装はされた](https://bugzilla.mozilla.org/show_bug.cgi?id=1811054)ものの[リリース優先度はさして高くない](https://bugzilla.mozilla.org/show_bug.cgi?id=1811059)、とかいう段階なので、一般的に書けるようになるのはまだまだ先です。

というか、そんな状態なのにFinished Proposalに入れるのか？


## [Symbols as WeakMap keys](https://github.com/tc39/proposal-symbols-as-weakmap-keys)

[WeakMap](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)のキーにSymbolを使えますよ、というProposal。

```js
const weakmap = new WeakMap();

const key = Symbol("key");
weakmap.set(key, 1); // OKになる

const key = "key";
weakmap.set(key, 1); // Uncaught TypeError: Invalid value used as weak map key
```

そもそもインスタンス使い捨てのJavaScriptで弱参照を使う理由がいまだによくわからない。
きっとライブラリとかツールチェーンとかで使われるのでしょう。たぶん。

ちなみに[他の人が上げていた懸念点](https://sosukesuzuki.dev/posts/symbols-as-weakmap-keys/)2点のうち、[Symbol.for()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for)で作ったSymbolの登録は[禁止されました](https://github.com/tc39/proposal-symbols-as-weakmap-keys/issues/21)。
well-knownなシンボルは許可されます。

```js
weakmap.set(Symbol.iterator, 1); // OK
weakmap.set(Symbol.for("key"), 1); // Uncaught TypeError: Invalid value used as weak map key
```

こちらは2022/11/29リリースの[Chrome 108](https://forest.watch.impress.co.jp/docs/news/1459736.html)から利用可能です。
CanIUseには[何故か出てこない](https://caniuse.com/?search=symbol%20WeakMap)。

# 感想

リリースされてもいないのにFinishedになったりとか、リンク先のRFCがStage 3のままさっぱり更新されていなかったりとか、なんというかこう政治的事情を感じたりしないでもないというかなんか。

具体的にどういう経緯があったのかはわかりません。
ミーティングはクローズドでありライブ配信やアーカイブもないみたいで、さらに[議事録](https://github.com/tc39/notes/tree/main/meetings)が公開されるまで数ヶ月かかるので、それまでは何があったかわからないんですよね。

と思ったけどよく考えたら私リスニングが駄目なのでライブ配信があったところでわからんかったわ。
まあきっと、もっと詳しい誰かがそのうち詳細な経緯とかも含めて解説してくれることでしょう。