JavaScript、はてなにドット「?.」
〜オプショナルチェーンについて。

〽️ エラーを回避するメリット。 〽️ 配列や関数にもつかえます。





JavaScriptコードの「?」をまとめたページはこちら⬆︎。



syntax。


obj.property 「「1?.」」property


評価しながら辿ってくれる。


こんにちは、「ふ」です。
JavaScriptコードの「これって何?」シリーズです。今回は、

(オブジェクト).(プロパティ) 「「1?.」」(プロパティ)

はてな「?」にドット「.」のついたもの。
どうやら、オブジェクトの深い層にアクセスしているようですが....

これは、オプショナルチェーン(条件付き呼び出し)と呼ばれるもので、 「?.」の左にある式を評価しながらアクセスするための表記です。
アクセスエラーによるプログラムのクラッシュを未然に防いでくれるので、安全なコーディングを可能にしてくれます。

⬆︎どーいうこと?

何を言っているのかわからない.................という方もいるでしょう。
⬇︎のような疑問を抱くかもしれません。



「評価しながら」←そもそも意味がわかりません。

 エラーを出すと何が困るのか?

「評価しながらアクセスする」とはどういうことなのか?
 何のメリットが?

したがって。

今回はいきなり「オプショナルチェーン」自体の解説に入るのではなく、
JavaScriptにおけるアクセスエラーが起きる現象とそのデメリット、それに対してオプショナルチェーンがなぜ役に立つのか。順を追って紹介させていただくことにします。

エラーとなるケース。


const player1 = { bbname:"taro" bb};

野球選手を登録するオブジェクト「player1」があったとします。


console.log(player1.name); 「「3▶︎ taro」」

nameプロパティを出力してみると、フツーにconsole.logされます。


console.log(player1.age); 「「3▶︎ undefined」」

片や。定義されていないプロパティを呼び出すと、「undefined」と出力されます。

これは、

player1というオブジェクトの中を探したのですが、
「age」というプロパティは定義されていません。

ということです。
ブラウザは「player1」にはちゃんとアクセスしていて、その中に「age」があるかどうか探した結果が、undefined。


const pleyer2 = { bbname:jiro, bbgrade:{ average:.300,HR:20 } };

「player2」も作りました。
今度は成績を表す「grade」プロパティも定義しました。そしてその中に、打率の「average」とホームラン数の「HR」プロパティを含めています。なかなか良いバッターです。

ここで、「player1のホームラン数も知りたい」と思った人がいました。
player1には「grade」や「HR」は定義されていないのですが、とりあへずアクセスしてみましょう〜 すると。

console.log(player1.grade.HR); 「「3▶︎ Uncaught TypeError: Cannot read properties of undefined (reading 'HR') 」」

今度は「undefined」ではなく、エラーとなりました。
エラーメッセージの内容としては、

「HR」というプロパティにアクセスしようとしたが、
そもそもplayer1には前提となる「grade」プロパティが定義されてません。

だから探すことすらできない。
よって、エラーとする。

といった厳しい対応が返ってきています。
なぜ「undefied」ではなく「error」となったのか。双方の処理を行った時のブラウザの動きを見てみましょう。

・最初のケースでは、「player1」にはアクセスできていて、その中の「age」を探しました。で、見つからなかったのでundefined。

・次のケースでは、「player1」にアクセス成功、その後「HR」を探すための「grade」にアクセスできなくて、エラー。

どうやら、対象の「1つ前のプロパティ」にアクセスできないとエラーになる模様です。

何でエラーだと困るの?


プログラムがエラーを吐くと、その後の処理が止まってしまいます。

console.log(player1.age); 「「3//undefined」」 alert("こんにちは");「「3//実行される」」

undefinedの後に、alert処理を加えました。
undefinedの場合にはプログラムは次の処理へと移行し、このalertは実行されます。


console.log(player1.grade.HR); 「「3//エラー」」 alert("こんにちは");「「3//実行されない」」

ところがエラーを起こした場合には、プログラムはそこで停止してしまいます。
次に続くalertは実行されません。

プログラム全体の実行途中に、ユーザの操作などでプロパティが不成立になる場合もあります。
あとからその不成立なプロパティへのアクセスがあると、そこで全体が停止してしまう。

これはwebサイトやアプリケーションにとっては大打撃です💧

オプショナルチェーンで解決。


オプショナルチェーンは、この問題を解決します。
先ほどのエラーとなった処理では、プロパティをただのドット「.」で辿っていました。これをオプショナルチェーン「.?」でつなぐとどうなるのか。

console.log(player1.grade 「「1?.」」 HR); 「「3▶︎ undefined」」

エラーではなく、「undefined」が返りました。

オプショナルチェーン「?.」は、自身の左にある式を評価しながら目的の「HR」を探してくれるのです。
「評価」とは、「成立しているかどうか」を調べること。対象が式ではなくプロパティなどであれば、「定義されているかどうか」が判定の基準となります。

そして、評価が「成立していない」となった場合、エラーにはならずにそこで探索はストップ。その時点で出ている結論である「undefined」を返して、次のコードへと進んでくれます。

player1.grade 「「1?.」」 HR

この⬆︎プロパティを探るチェーンは、次のような指示を送っています。

「HR」を探す前に先づ、「grade」が定義されているかどうか評価してね。
「grade」が成立していなければ「undefined」ということで..

〜次の処理に移ってください。


指示を受け取ったブラウザは⬇︎のような行動をとります。

player1 ← 確かに存在する。
grade ← player1にはこのプロパティは定義されていないよ。

〜だから以下の処理はスルーし、次のコード内容に進みます。現時点での結論である「undefined」を返しておきますね。

という優しい対応をしてくれます。

A→B→C→Dというプロパティのチェーンがあったとしましょう。
ここで、「B」は未定義です。

通常のプロパティチェーンの場合、目的のプロパティ以前にある経路を一括りに評価し、成立していなければ即エラーを吐き出します。

オプショナルチェーンを使えば、探索はそこで一旦立ちどまり、「?.」の左にあるものを評価します。
もし成立していなければ以降の探索は打ち切り。「undefined」を返して次なるコードへと進んでくれます。

エラーとはせず、「なかったこと」にしてくれるんですね。これで「プログラム全体の停止」という危機的状況は回避できます。

if文で書くと長い。

ちなみにこれをif文で書くとすると、次のようになります。

if(!player1.grade) { bbconsole.log("undefined"); bb} else { bbconsole.log(player1.grade.HR); }

結構な量のコードになってしまいますね。
この例ではプロパティ階層は2段階ですが、もっと深い場合にはif文大会になってしまいます。

オプショナルチェーンを使うと簡単に書くことができるので、便利です。

関数や配列要素を条件付き呼び出し。


オプショナルチェーンは、関数や配列などにも利用できます。


関数のバヤイ。


const obj = { bbfuncA:function() {console.log("A");} bb};

「funcA」という関数が定義されたオブジェクト。
ここで、外部から定義されていない「obj→funcB」をわざと実行してみます。


obj.funcB(); 「「3▶︎ error」」

普通に呼び出すと、もちろんエラー。


obj.funcB 「「1?.」」(); 「「3▶︎ 何も起きず」」

関数の丸括弧の前に「?.」を置くことで、エラーを吐かずに「何もなかったこと」にしてくれます。

配列のバヤイ。


let arr = [ bb["a","b"], bb["c","d"] ];

配列が入れ子になった「arr」があるとします。arrの要素は2つしかありません。
またもや3つ目の要素にわざとアクセスしてみましょう。


console.log(arr[2][0]); 「「3▶︎ error」」

もう予想はつきますね笑
フツーにアクセスするとエラーです。


console.log(arr[2]「「1?.」」[0]); 「「3▶︎ undefined」」

indexの後ろに「?.」を挟むと「undefined」としてくれました。

規模が大きくなると重宝します。


最後までお読みくださり、ありがとうございます。
今回はオプショナルチェーンについて紹介してきました。JavaScript初学者の方にとっては「何の役に立つのか?」〜ピンと来ないかもしれません。

でもそのうち。スキルアップを遂げて規模の大きいコードを書くようになってくれば、個々のプロパティや関数が一目で把握できなくなってきます。そのときには「?.」を使うことで、クラッシュしない安全なコーディングが実現します。今のうちにぜひ覚えておいてください。


この記事 . 役に立った ?. またお会いしましょう。

⬆︎undefinedにならないで欲しい笑





JavaScriptのはてな「?」とコロン「:」〜条件演算子について。

2022.01.18
if文の代わりになるのか?


JavaScript、乱数の範囲や重複を指定〜Math.random使い方。

2021.11.17
整数/範囲/重複の有無を自在にあやつろう。

JavaScriptの矢印「=>」〜これはアロー関数というものです。

2022.01.09
使い方とメリットについて解説。


ブログのクリックをGoogle Analyticsで計測。

2021.11.30
新たなツールは導入せずともOK。











「ふ」です。

swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。