JavaScript勉強し直しててへーと思った演算子

以前はサーバーサイドの実装がメインであまりJavaScriptを書く機会が無かったのですが、最近はJavaScript書く機会も多くなってきたのでこれを機に、MDN読み直してJavaScriptに再入門してみたのでそのメモです。

## null合体演算子

* [Null 合体 (??) - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator)

名前からして??って感じですが、

> Null 合体演算子は左辺が null または undefined の場合に右辺の値を返します。

という機能のようです。
そう言えば、

```JavaScript
const a = b === null ? 'c' : b
```

って書く事たまにあると思いますが、それが

```JavaScript
const a = b ?? 'c'
```

となるイメージですね。

* [Null合体演算子 - Wikipedia](https://ja.wikipedia.org/wiki/Null%E5%90%88%E4%BD%93%E6%BC%94%E7%AE%97%E5%AD%90)

Wikipediaみると、他言語でも割と採用されている文法のようです。

## Null 合体代入

* [Null 合体代入 (??=) - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment)

> Null 合体代入 (x ??= y) 演算子は、x が nullish (null または undefined) である場合にのみ代入を行います。

こちらは、null合体後ににその結果を代入する感じです。 +=演算子や-=演算子のnull合体バージョンみたいなものでしょうか。
しかし、最近の傾向として、JavaScriptでもなるべく再代入は避けるスタンスのコードが多いので使う機会は滅多に無さそうです。

## カンマ演算子

* [カンマ演算子 (,) - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Comma_Operator)

> カンマ演算子 (,) は、それぞれの演算対象を（左から右に）評価し、最後のオペランドの値を返します。これにより、複数の式が評価される複合式を作成することができ、複合式の最終値はそのメンバ式の一番右端の値となります。

個人的に意外な盲点だったのが、カンマ演算子です。これ、演算子だったんだという。。。

```JavaScript
console.log((1, 2)) // => 2
```

という事のようで、英語版のWikipedia見た感じだと、C/C++などで実装されている演算子のようです。

* [Comma operator - Wikipedia](https://en.wikipedia.org/wiki/Comma_operator)

便利な文法というよりは、何かしらのバグの原因になる確率の方が高そうな演算子ですね。複数の式を並べて書けるというのが売りのようですが、副作用をなるべく避けるという現代のプログラミングのスタンスにおいては、その真価を発揮できるシチュエーションは少ないかも知れません。どちらかというと、上手くコードが動かない時に疑ってみるポイントの一つになりそうかな、と思います。

## Optional chaining (?.)

* [Optional chaining (?.) - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining)

> オプショナルチェイニングoptional chaining演算子 ?. は、接続されたオブジェクトチェーンの深くに位置するプロパティの値を、チェーン内の各参照が正しいかどうかを明示的に確認せずに読み込むことを可能にします。 ?. 演算子の機能は . チェーン演算子と似ていますが、参照が nullish (null または undefined) の場合にエラーとなるのではなく、式が短絡され undefined が返されるところが異なります。 関数呼び出しで使用すると、与えられた関数が存在しない場合、 undefined を返します。

Optional chainingは他言語でも色々形は違えどよく採用されている記法ですね。ES2020で追加されているとは。。。不勉強でした。。。

## in演算子

* [in - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/in)

> in 演算子は、指定されたプロパティが指定されたオブジェクトにある場合に true を返します。

```JavaScript
const x = { a: "1", b: "2" }

console.log("a" in x)  // => true
console.log("c" in x)  // => false
```

Pythonのin演算子に見た目は非常によく似ていますが、配列(Array)の時の挙動が全く異なるので要注意ですね。

Pythonの場合、

```Python3
3 in [1, 2, 3] // => True
```

なのですが、JavaScriptの場合、

```JavaScript
3 in [1, 2, 3] // => false
```

となってしまいます。理由は、Pythonが「その要素が配列に含まれているかどうか」を見ているのに対し、JavaScriptは「インデックスの指す値ではなく、インデックスの数字が含まれているか」を見ています。JavaScriptだとこの場合は[Array.prototype.includes()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)を使うのが正解のようです。
というわけで、Pythonユーザにとっては初見殺しポイントになってしまいます。

## void演算子

* [void 演算子 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/void)

> この演算子は、「戻り値が undefined であってほしい場所に、それ以外の戻り値を持つ式を挿入したい場合」に有用です。

よく、`href="javascript:void(0);"`とかで使われるvoidって演算子の扱いだったんですね。JavaやC言語のイメージのせいで何かしらのオブジェクト型の表現か構文か何かだと思っていました。「戻り値が undefined であってほしい場所に、それ以外の戻り値を持つ式を挿入したい場合」に使うというのは良いのですが、それだとカンマ演算子で代替出来てしまうような。。。

## おわりに

言語仕様を読み返してみるのも大切ですね。上記以外にも割と知らない知識がちょこちょこありました。

## 参考文献

* [JavaScript リファレンス - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference) (Last modified: 2020年11月13日版)