〽️ エラーを回避するメリット。 〽️ 配列や関数にもつかえます。
JavaScriptコードの「?」をまとめたページはこちら⬆︎。
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(!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、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。