💻

onClick?.(e) の「?.」is 何:オプショナルチェイニングを使った関数実行【JS】

2022/02/14に公開

「?.」はJavaScriptの演算子

その名を「オプショナルチェイニング(optional chaining)」という。
これはJavaScriptの記法であり、演算子である。

オブジェクトのプロパティ値がない場合への対策

オブジェクトのプロパティがオブジェクトで、さらにそのプロパティがオブジェクトで...という場合、
最終的に欲しい(一番底の)プロパティ値を取得する処理は、以下のように書ける。

オプショナルチェイニングを使わない場合の問題点

const obj1 = {prop1:{prop2:{prop3:'底のプロパティ値だよ',},},};
console.log(obj1.prop1.prop2.prop3);    // '底のプロパティ値だよ'

しかし途中のプロパティ値が設定されていないオブジェクトに出会った場合、どうだろう?

const obj1 = {prop1:{propX:{prop3:'底のプロパティ値だよ',},},};
console.log(obj1.prop1.prop2.prop3);    // [ERR]: undefined is not an object (evaluating 'obj1.prop1.prop2.prop3') 

都度プロパティに正しく値がセットされているか?を確認すればいいかもしれない。

const obj1 = {prop1:{propX:{prop3:'底のプロパティ値だよ',},},};
console.log(obj1.prop1 && obj1.prop1.prop2 && obj1.prop1.prop2.prop3);    // undefined

だがそのためには膨大なコードを書く必要が出る。実際に書いていてスゲーめんどくさい。

オプショナルチェイニングを使った記法

.の前に?を入れることで、?の前の部分がnull or undefinedとなった時点で処理を中断し、undefinedを返す。

const obj1 = {prop1:{propX:{prop3:'底のプロパティ値だよ',},},};
console.log(obj1?.prop1?.prop2?.prop3);    // undefined
console.log(obj2?.prop1?.prop2?.prop3);    // 未宣言のオブジェクトobj2のためエラー

まあとはいえ、全部の.を?.にすることは望ましくないですね。
プロパティを生成/setするコードの中でnullやundefinedが制約済みのプロパティについては?.を記載する必要性はないでしょう。

それで?.()は何?

存在しない可能性のある関数を呼び出すときに使う

onClick?.(e)の場合、「onClick関数があるか(定義済みか)どうかわからない、あれば実施、無ければスルーして良い」となるわけです。

const func =  {
    onClick() {
        console.log('onClickされたよ');
    }
}
console.log(func.onClick?.());    // [LOG]: "onClickされたよ"
console.log(func.onClick123?.());    // [LOG]: undefined 

参考

https://ja.javascript.info/optional-chaining
MDNよりわかりやすかった。
注).?についてMDNでは演算子と呼んでますが、参考では演算子じゃないと書かれています。
この辺は演算子is何?を明確にしてまたエントリしたいところ。

https://typescriptbook.jp/reference/values-types-variables/object/properties-of-objects
そもそもオブジェクトのプロパティとして関数書けるけど、短縮の書き方知らなくて詰んだので。
しかも厳密には関数ではなくメソッドです。

Discussion