LoginSignup
0
0

More than 1 year has passed since last update.

【Javascript】Optional_chaining(追加的な?選択的な?連鎖)について

Last updated at Posted at 2021-05-30

初めに

Optional_chaingについて学習した内容のoutput用記事です。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。

Optional_chainingとは

MDNの公式ドキュメントには次のように書かれています。

接続されたオブジェクトチェーンの深くに位置するプロパティの値を、チェーン内の各参照が正しいかどうかを明示的に確認せずに読み込むことを可能にします。

「.」チェーンプロパティーと似ていますが、プロパティーの有無に関わらずエラーを出さずに調べたいプロパティーの値を読み込むことができます。言葉だけでは難しいので、早速使ってみることに。

Optional_chainingを使わない時の問題について

まず、「.」チェーンプロパティーを使うために、次のようなobjectを用意します。

  const stores = {
        bookStore: {
          mon: { open: 10, close: 20 },
          tue: { open: 11, close: 19 },
        },
      };

storesの中のbookStoreにはmonとtueがあり、それぞれのmonとtueにはopenとcloseの値が入っています。もし、このような構造を知らずに、外部の利用者がsunにもopenとcloseの値があると思い、値を取り出す場合を考えてみます。

console.log(stores.bookStore.sun.open);    //エラーになる

このように書くと次のようなエラーが出ます。
スクリーンショット 2021-05-30 8.55.02.png
今度はif文を使ってstores.bookStore.sun.openが存在すればという条件を付けてみます。

if (stores.bookStore.sun.open) console.log(stores.bookStore.sun.open);    //エラーになる。

同じようなエラーになります。
スクリーンショット 2021-05-30 8.57.07.png
これはsotresの一番深い階層のopenプロパテーの有無を判定するためには、さらにその前のsunプロパティーが存在するかどうかを判定する必要があるからです。
なので&&演算子を使って次のように書き直す必要があります。

if (stores.bookStore && stores.bookStore.sun)

    console.log(sotres.bookStore.sun.open);  //エラー画面が表示されない

このようにするとエラーにはなりませんが、書き方的には長いです。1つのプロパティーだけならいいんですが、複数ある場合は大変です。さらに階層が深くなれば深くなるほど、if文は長くなるので尚更です。

Optional chainingを使ってみる

sunにopenプロパティーがあればopenの値をコンソールに表示したい場合、optional chainingを使うと以下のように記述できます。

console.log(stores.bookStore.sun?.open);

結果は以下の通り。
スクリーンショット 2021-05-30 9.06.32.png
存在しないので、undefinedと表示されます。「.」メソッドの前に「?」を付けるだけなので、とても簡単です。
もちろん、sunが存在するかどうかも分からない場合にはsunの前に「?.」を付けます。

console.log(stores.bookStore?.sun?.open);

結果は同じくundefinedです。
スクリーンショット 2021-05-30 9.06.32.png

monからsunまでの曜日が入っている箱をdaysに格納し、for of文を使ってコンソールに表示してみます。

const stores = {
        bookStore: {
          mon: { open: 10, close: 20 },
          tue: { open: 11, close: 19 },
        },
      };

//以下を追記
const days = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];

for (const day of days) {
     const open = stores.bookStore[day]?.open;
     console.log(`${day}: ${open}時に開きます。`);
     }

「?.」を使うとbookStore[day]にopenプロパティーが存在するかどうかでundefined、またはそのプロパティーの値を返してくれます。
スクリーンショット 2021-05-30 9.21.23.png

objectのメソッドが存在しない場合にも対応できます。

//中略
console.log(stores.add?.(2, 5));

sotresオブジェクトにはaddというメソッドは存在しないので「?.」を使うと次のようにundefinedを返してくれます。
スクリーンショット 2021-05-30 9.06.32.png

ここでundefinedと表示させたくないので、前回学んだ(??)合体演算子を使ってみます。

console.log(stores.add?.(2, 5) ?? "存在しないメソッドです。");

stores.add?.(2, 5)がundefinedで評価されず、"存在しないメソットです。"が表示されます。
スクリーンショット 2021-05-30 9.37.30.png

optional chainingを使うと条件分岐を書く必要が無くなります。
次のような場面でnameが存在するかしないかによってnameの値を表示するもしくは"木は存在しません。"という処理を簡潔に書くことができます。

const trees = [{ name: "ヒノキ" }, { numbers: 3 }];

console.log(trees[0]?.name ?? "木は存在しません。");

スクリーンショット 2021-05-30 9.50.46.png

同じ処理をoptional chainingを使わない場合だと以下のように記述しなければなりません。

if (trees.length > 0) console.log(trees[0].name);
else console.log("木は存在しません。");

可読性も悪くなるし、記述も長くなってしまいます。このようにOptional Chainingはとても便利な機能なので、これからも使ってみたいと思いました。

参考サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0